我正在使用Alchemy-Websockets作为服务器,我在服务器上自己的线程中发送和接收来自外部客户端的消息。 这很好用,但现在我还想在不同的线程中发送源自服务器的消息。 这是我的主要设置:
public WebSocket(int port, IRedisClient _redis)
{
Console.WriteLine("Server at " + port);
Redis = _redis;
// instantiate a new server - acceptable port and IP range,
// and set up your methods.
//clients = new Dictionary<string, UserContext>();
subscriber_list = new Dictionary<string, Dictionary<string, UserContext>>{ };
var aServer = new WebSocketServer(port, System.Net.IPAddress.Any)
{
OnReceive = OnReceive,
OnConnect = OnConnect,
OnConnected = OnConnected,
OnDisconnect = OnDisconnect,
TimeOut = new TimeSpan(0, 5, 0)
};
aServer.Start();
}
此代码位于在其自己的线程上启动的类中。 问题是,如果我想将数据发送到此 websocket 的客户端,如何处理多线程? 我是否只是添加一个锁定机制,以便特定的"用户上下文"不会在我使用它的同时使用? 我是否在 aServer.Start() 行之后放置一个 while 循环,并在我正在等待的基于服务器的通信上阻止? 喜欢这个?:
aServer.Start();
while(true){
// block on messages from my other thread (not from the websocket)
// get lock for a user context
UserContext.Send(myMessage);
Thread.Sleep(1000);
}
Thread.Sleep 并不意味着导致 websocket 休眠并错过通过套接字的消息。 看看其他例子,我认为这不应该发生,因为炼金术服务器也在自己的线程中。
Alchemy 在内部是异步的,但如果使用 while(true) + Thread.Sleep
阻止处理程序,则可能会阻止连接并阻止执行线程对等连接。
您应该在某处注册UserContext
,例如由客户端 ID 或用户 ID 或用户 ID + 连接 ID 关联的当前连接列表。每次你想向用户发送东西时,你都会浏览该列表,找到连接并发送东西。您必须小心并确保不会从同一UserContext
中的两个线程写入,因此请考虑使用生产者/消费者模式。
有很多很多方法可以做到这一点。但是,您不能只使用无限循环来阻止事件处理程序。