这肯定已经被问了一千次,但是我没有找到任何令人满意的答案,所以我会尝试另外一次,尽可能清楚。
我开始使用干净的Express;通常通过以下终端命令完成的那个:
user$ express
user$ npm install
然后我继续安装socket.io,这样:
user$ npm install socket.io --save
在我的main.js文件中,我有以下内容:
//app.js
var express = require('express'),
http = require('http'),
path = require('path'),
io = require('socket.io'),
routes = require('./routes');
var app = express();
我将socket.io服务器附加到我的快递服务器上来启动它:
//app.js
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('express server started!');
});
var sIo = io.listen(server);
我现在要做的是设置Express的常用路径:
//app.js
app.get('/', routes.index);
app.get('/send/:recipient/:text', routes.sendMessage);
现在,由于我喜欢将事情组织起来,我想将socket.io代码放在另一个文件中,所以不要使用通常的代码:
//app.js
sIo.sockets.on('connection', function(socket){
console.log('got a connection');
});
我使用以下内容来访问套接字和 sIo对象(因为该对象包含所有连接信息(重要)):
//app.js
sIo.sockets.on('connection', function(socket){
routes.connection(sIo, socket);
});
// index.js (./routes)
exports.connection = function(sIo, socket){
console.log('got a connection.');
};
这样我就可以在这里完成所有socket.io工作。我知道我现在可以从sIo对象访问我的所有客户信息,但当然,它们不包含有关其会话数据的任何信息。
我现在的问题如下:
假设用户发出HTTP请求发送消息,我的路由中的处理程序是这样的:
exports.sendMessage = function(req,res){ //在这里做点什么 };
如何让我在socket.io中“发送”某些东西来发送消息?我不想知道需要完成的所有基础工作,比如跟踪消息,用户等。我只想了解如何“解雇”socket.io来做某事。
提前致谢。
答案 0 :(得分:3)
// index.js (./routes)
var EventEmitter = require('events').EventEmitter;
module.exports.messageEmitter = messageEmitter = new EventEmitter();
module.exports.sendMessage = function(req, res) {
messageEmitter.emit('private_message', req.params.recipient, req.params.text);
};
问题2:您可以在初始连接时访问套接字。一个主要借用this answer的例子:
var connect = require('connect'),
userMap = {};
routes.messageEmitter.on('private_message', function(recipient, text) {
userMap[recipient].emit('private_message', text);
});
io.on('connection', function(socket_client) {
var cookie_string = socket_client.request.headers.cookie;
var parsed_cookies = connect.utils.parseCookie(cookie_string);
var connect_sid = parsed_cookies['connect.sid'];
if (connect_sid) {
session_store.get(connect_sid, function (error, session) {
userMap[session.username] = socket_client;
});
}
socket_client.on('private_message', function(username, message) {
userMap[username].emit(private_message, message)
});
});
所以我们只是在会话的用户名和套接字连接之间创建一个映射。现在,无论何时需要发送消息,您都可以轻松查找与该用户关联的套接字,并使用其套接字向他们发送消息。只需确保处理断开连接,并在多个选项卡中重新连接和连接等。
答案 1 :(得分:0)
我已经建立了类似你所说的东西。如果用户可以发出套接字请求,它会通过套接字推送消息,然后服务器进行广播或发送。但是,如果用户无法连接到套接字,则它会执行http发布,就像调用sendMessage所说的那样。我做了什么,而不是让sendMessage从套接字中射出,我也让我的客户每5秒左右做一次ajax请求。这将带回新消息,如果没有通过socket.io接收任何消息,我将它们添加到我的客户端数组。这可以作为一种安全网,所以我不必总是完全信任socket.io。
请参阅下面的伪代码
客户端
if canSendSocketMessage()
sendSocketMessage(message)
else
sendAjaxMessage(message)
setInterval( ->
// ajax call
getNewMessages()
), 5000
服务器
套接字
socket.on 'message' ->
saveMessage()
socket.emit(message)
ajax端点
app.post 'sendMessage'
saveMessage()
app.get 'getNewMessages'
res.send getNewMessages()