我正在尝试构建基于websocket的应用程序。
我想知道是否可以向所有活动连接发送消息,因为它们是持久的。
假设我正在运行一个实时拍卖网站,并且我有多个用户正在观看拍卖页面,每个用户都通过套接字连接到我的服务器。现在让我们说一个用户提高出价。我想向所有连接的客户端发送消息。最简单的方法是让客户端每秒通过套接字轮询服务器,但我认为websockets的想法是进行真正的双向通信。
如何做到这一点?
提前感谢,
Rotem公司
答案 0 :(得分:6)
socket.io解决方案:
// note, io.listen() will create a http server for you
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
io.sockets.emit('this', { will: 'be received by everyone' });
socket.on('private message', function (msg) {
console.log('I received a private message from ', socket.id, ' saying ', msg);
// Echo private message only to the client who sent it
socket.emit('private message', msg);
});
socket.on('disconnect', function () {
// This will be received by all connected clients
io.sockets.emit('user disconnected');
});
});
all_active_connections = {};
webocket server(有many),手动执行:
var ws = require("ws");
global_counter = 0;
all_active_connections = {};
ws.createServer(function (websocket)
{
websocket.on('connect', function()
{
var id = global_counter++;
all_active_connections[id] = websocket;
websocket.id = id;
}).on('data', function (data) {
if (data == 'broadcast me!')
{
for (conn in all_active_connections)
all_active_connections[conn].write(data);
}
}
}).on('close', function() {
delete all_active_connections[websocket.id];
});
}).listen(8080);
答案 1 :(得分:4)
对于基于tornado / tornadio的解决方案,您的SocketConnection类需要维护类级别的连接列表。您的on_connect处理程序会将连接添加到此列表中,on_close会将其删除。有关样本伪代码,请参阅Serge S. Koval的this post。代码重现如下:
声明您的TornadIO连接类:
class MyConnection(SocketConnection):
participants = set()
@classmethod
def broadcast(cls, msg):
for p in cls.participants:
p.send(msg)
@classmethod
def controller_msg(cls, msg):
cls.broadcast(msg)
在您的设备轮询线程中,执行以下操作:
while True:
datum = file.readline()
if len(datum) > 2:
t = json.loads(datum)
...
def callback():
MyConnection.controller_msg(t)
io_loop.add_callback(callback)
此外,gevent-socketio支持消息广播,但它基于gevent,而不是龙卷风。
tornadio2已经维护了一个活动会话列表,所以您需要做的就是:
class MyConnection(SocketConnection):
def broadcast(self, event, message):
for session_id, session in self.session.server._sessions._items.iteritems():
session.conn.emit(event, message)
这是有效的,因为每个连接实例都有对其会话的引用,该会话引用了用于创建应用程序的全局路由器(存储为server
),该路由器维护{{1}中的会话列表SessionContainer
中的对象。现在,只要您想在连接类中广播消息,只需执行以下操作:
_sessions
答案 2 :(得分:2)
这个redis + websockets (on tornado)示例可以帮助您。基本上,您有一个应该被通知的听众列表,并且一旦收到消息,就会迭代该列表并通知他们。