为什么客户端在节点+快递+socket.io+翡翠简单应用中断开连接再重新连接

Why is client disconnecting and reconnecting in node + express + socket.io + jade simple app

本文关键字:中断 应用 简单 断开 连接 重新连接 节点 客户端 快递 io+ +socket      更新时间:2023-09-26

我创建了一个简单的应用程序,试图集成node,express,socket.io 和jade。 用户在文本字段中输入一些字符串("工具 ID"),然后单击提交按钮。 该文本只是转换为全部大写,结果将附加到页面上的结果部分。 对于查看页面的其他客户端,结果应自动更新。

它主要有效。 但是,问题在于,在用户单击页面上的提交按钮以提交工具 ID 后,节点控制台和浏览器 javascript 控制台都显示客户端断开连接,然后重新连接。

对于用户来说,结果似乎在几分之一秒内正确更新。 然后结果又空白了几分之一秒。 然后重新显示结果。 由于我在结果中显示用户的会话 ID,因此我可以看到会话 ID 在短时间内发生了变化,而结果变为空白。

请注意,如果其他客户端只是查看页面,但没有进行交互,则结果会顺利更新(没有短暂的结果变为空白),并且该客户端似乎根本没有断开连接。

我不希望客户端在单击表单上的提交按钮时断开连接并重新连接。 有人可以告诉我为什么会发生这种情况以及我应该如何正确地做到这一点吗?

我的应用.js(服务器)

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
io = require('socket.io').listen(server); // without the var, this becomes available to other files like routes.
var path = require('path');
var routes = require('./routes/routes');
var process = require('./routes/process');
var _ = require("underscore");
// all environments
app.set('port', 3097);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
//app.use(express.logger('dev'));
app.use(express.bodyParser()); //Tells server to support JSON, urlencoded, and multipart requests
app.use(express.methodOverride());
app.use(express.cookieParser('i7iir5b76ir857bveklfgf'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
var toolIDs = [];
// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}
io.on("connection", function(socket) {
    console.log("Client connected.  Sending Update");
    socket.on("toolsRequest", function() {
        socket.emit('toolsReady', {toolIDs: toolIDs}); //This should go to the client that just connected.
    });
    socket.on("disconnect", function() {
        console.log("Client Disconnected");
    });
    socket.on("toolsUpdate", function(data) {
        processedToolID = process.process(data.toolID);
        toolIDs.push({id: data.id, inputToolID: data.toolID, outputToolID: processedToolID}); 
        io.sockets.emit("toolsUpdated", {toolIDs: toolIDs}); //This should go to all clients
        console.log('Results Updated - notifying all clients');
    });
});
// display main page
app.get('/', routes.home);
server.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

我的路线.js

/*
 * GET home page.
 */
exports.home = function(req, res){
    res.render('home', { title: 'Tool'});
    console.log("Just called route.home");
};

我的家.翡翠

doctype 5
html
    head
        title= title
        link(rel='stylesheet', href='/bootstrap/css/bootstrap.min.css')
        link(rel='stylesheet', href='/bootstrap/css/bootstrap-responsive.min.css')
        script(src='/socket.io/socket.io.js')
        script(src="http://code.jquery.com/jquery.min.js")
        script(src='/js/index.js')
block content
    #wrapper
    h1 
        a(href='/') TOOL
    #display
        div.row-fluid
            div.inlineBlock
                form#toolForm
                    label Tool ID
                    input(type="text", placeholder="e.g. abc123")#toolID
                    span.help-block You may enter a string.
                    button(class="btn")#submit
                        | Submit
                br
            div.inlineBlock.topAligned
                h2 Results
                br
                div#results
                br

我的索引.js(客户端)

function init() {
    /* 
    On client init, try to connect to the socket.IO server.
    */
    var socket = io.connect('http://example.com:3097/');
    //We'll save our session ID in a variable for later
    var sessionID = '';
    //Helper function to update the results  
    function updateResults(toolIDs) {
        $('#results').html('');
        for (var i = 0; i < toolIDs.length; i++) {
            $('#results').append('<span id="' + toolIDs[i].id + '">' + '<b>Creator ID:</b> ' + toolIDs[i].id + ' <b>Your ID:</b> ' + sessionID + ' <b>Input Tool:</b> ' + toolIDs[i].inputToolID + ' <b>Output Tool:</b> ' + toolIDs[i].outputToolID + (toolIDs[i].id === sessionID ? '<b>(You)</b>' : '') + '<br /></span>');
        } 
    }
    /*
    When the client successfully connects to the server, an
    event "connect" is emitted.
    */
    socket.on('connect', function () {
        sessionID = socket.socket.sessionid;
        // Note this appears in the browser Javascript console, not node console
        console.log('You are connected as: ' + sessionID);    
        socket.emit('toolsRequest'); //Request the tools data so we can update results
    });
    socket.on('toolsReady', function(data) {
        updateResults(data.toolIDs);
        console.log('Results have been updated from socket.on.toolsReady');  
    });
    socket.on('toolsUpdated', function (data) {
        updateResults(data.toolIDs);
        console.log('Results updated from socket.on.toolsUpdated');
    });
    /*
    Log an error if unable to connect to server
    */
    socket.on('error', function (reason) {
        console.log('Unable to connect to server', reason);
    });
    function getCitations() {
        var toolID = $('#toolID').val()
        socket.emit('toolsUpdate', {id: sessionID, toolID: toolID});
    }
    $('#submit').on('click', getCitations);
}
$(document).on('ready', init);

以下是客户端单击提交按钮时我在节点控制台中看到的内容:

 debug - websocket writing 5:::{"name":"toolsUpdated","args":[{"toolIDs":[{"id":"5a1dfX2dmxcogYT_11e8","inputToolID":"a123123","outputToolID":"A123123"},{"id":"OIuqao6TsTeddQm111e-","inputToolID":"1abcdefg","outputToolID":"1ABCDEFG"},{"id":"Qr_YQ2ZhQHbDpBlk11e_","inputToolID":"abcdefg","outputToolID":"ABCDEFG"}]}]}
Results Updated - notifying all clients
Just called route.home
   info  - transport end (socket end)
   debug - set close timeout for client Qr_YQ2ZhQHbDpBlk11e_
   debug - cleared close timeout for client Qr_YQ2ZhQHbDpBlk11e_
   debug - cleared heartbeat interval for client Qr_YQ2ZhQHbDpBlk11e_
Client Disconnected
   debug - discarding transport
   debug - served static content /socket.io.js
   debug - client authorized
   info  - handshake authorized 2bPKGgmLdD4fp-vz11fA
   debug - setting request GET /socket.io/1/websocket/2bPKGgmLdD4fp-vz11fA
   debug - set heartbeat interval for client 2bPKGgmLdD4fp-vz11fA
   debug - client authorized for
   debug - websocket writing 1::
Client connected.  Sending Update
   debug - websocket writing 5:::{"name":"toolsReady","args":[{"toolIDs":[{"id":"5a1dfX2dmxcogYT_11e8","inputToolID":"a123123","outputToolID":"A123123"},{"id":"OIuqao6TsTeddQm111e-","inputToolID":"1abcdefg","outputToolID":"1ABCDEFG"},{"id":"Qr_YQ2ZhQHbDpBlk11e_","inputToolID":"abcdefg","outputToolID":"ABCDEFG"}]}]}

谢谢,感谢您的帮助。

您的提交按钮实际上是在重新加载页面,这就是套接字断开连接的原因,以及您在这么短的时间内看到套接字响应的原因。只需阻止提交按钮的默认操作即可。更改此设置:

$('#submit').on('click', getCitations);

类似的东西:

$('#submit').click(function(event) {
  event.preventDefault();
  getCitations();
});