2

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

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

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

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

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

我的app.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");
};

我的家.jade

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

我的index.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"}]}]}

谢谢,我很感激帮助。

4

1 回答 1

1

您的提交按钮实际上是在重新加载页面,这就是套接字断开连接的原因,也是您在这么短的时间内看到套接字响应的原因。只是阻止提交按钮的默认操作。改变这个:

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

类似的东西:

$('#submit').click(function(event) {
  event.preventDefault();
  getCitations();
});
于 2013-09-22T19:33:56.913 回答