我创建了一个简单的应用程序,尝试集成node,express,socket.io和jade。用户在文本字段中输入一些字符串(“工具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'));
});
我的 routes.js
/*
* GET home page.
*/
exports.home = function(req, res){
res.render('home', { title: 'Tool'});
console.log("Just called route.home");
};
我的 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"}]}]}
谢谢,感谢您的帮助。
答案 0 :(得分:1)
您的提交按钮实际上正在重新加载页面,这就是套接字断开连接的原因,以及为什么您在短时间内看到套接字响应。只是阻止提交按钮的默认操作。改变这个:
$('#submit').on('click', getCitations);
类似的东西:
$('#submit').click(function(event) {
event.preventDefault();
getCitations();
});