我有一个启动服务器的类:
public class SocketServer
{
private static IXSocketServerContainer server = null;
public SocketServer()
{
server = XSockets.Plugin.Framework.Composable
.GetExport<IXSocketServerContainer>();
}
public bool StartServers()
{
try
{
server.StartServers();
return true;
} catch
{
return false;
}
}
这个类有一个方法:
public void SendEventMessageToAllClients(string message)
{
XSockets.Core.XSocket.Helpers.XSocketHelper
.SendToAll<MyController>(new MyController(), message, "events");
}
其中MyController
是我自己的控制器,它已实现,服务器可以找到它并且此方法有效。
现在我想用一种新方法扩展功能,允许我将事件发送给特定客户端:
public void SendEventMessageToClient(string clientId, string message)
{
XSockets.Core.XSocket.Helpers.XSocketHelper
.SendTo<MyController>(new MyController(),
p => p.ClientId == clientId, message, "events");
}
这是正确的做法还是我做错了什么?
谢谢!
答案 0 :(得分:7)
我不会推荐这种方法,我甚至没有测试过这种方法是否有效。
每次只能创建一个新的控制器才能访问扩展方法。 我猜测,因为你在启动服务器的类上有这个,你只能用它作为发布者吗?
如果是这样,正确的方法是安装XSockets.Client包并使用客户端池发布消息:client pool documentation
客户端池的优点在于您不需要每次都创建实例。池将重用您与控制器的连接。 使用客户端池(或真实客户端连接)将确保消息通过管道和所有拦截器(如果有)。直接使用控制器实例永远不会到达pipline,拦截器等。
//Get a pool client
ClientPool poolClient =
XSockets.Client.ClientPool.GetInstance("ws://127.0.0.1:4502/MyController", "*");
public void SendEventMessageToClient(Guid clientId, string message)
{
poolClient.Send(new {clientId, message}, "SendEventMessageToClient");
}
public void SendEventMessageToAllClients(string message)
{
poolClient.Send(message, "SendEventMessageToAllClients");
}
public void SendEventMessageToClient(Guid clientId, string message)
{
this.SendTo(p => p.ClientId == clientId, message, "SendEventMessageToClient");
}
public void SendEventMessageToAllClients(string message)
{
this.SendToAll(message, "SendEventMessageToAllClients");
}
如果你决定使用你已经完成的方式,至少应该在控制器的一个实例上创建以使用服务器类。
重要提示:直接使用控制器实例永远不会到达pipline,拦截器等。
//Be aware of the fact that this controller NEVER will have a connection.
//It can only send to others, it can never receive messages!
MyController c = new MyController();
//You should probably have a Guid here instead of string
//Also note that the client have to subscribe for "events" to get the message
public void SendEventMessageToClient(Guid clientId, string message)
{
this.SendTo(p => p.ClientId == clientId, message, "SendEventMessageToClient");
}
public void SendEventMessageToAllClients(string message)
{
this.SendToAll(message, "SendEventMessageToAllClients");
}
因为我不知道你要完成什么我不确定这是最好的方法,但上面的一个方法应该有用。
编辑:另外,在实际的应用程序中,您可能无法访问MyController类,因为它可能位于编译时未引用的单独程序集中。那么你的方法甚至是不可能的,然后去的方法是客户端或客户端池/ Uffe
答案 1 :(得分:0)
Uffe,你是对的ClientPool对我来说是正确的选择,我在运行你的代码时遇到了问题,因为你提出的一些映射不起作用,这里是你提出的解决方案略有修改以使其运行:< / p>
//Get a pool client
ClientPool poolClient = XSockets.Client.ClientPool.GetInstance("ws://127.0.0.1:4502/MyController", "*");
向控制器发送消息的方法。在这种情况下需要ITextArgs
public void SendEventMessageToClient(Guid clientId, string message)
{
ITextArgs textargs = new TextArgs(mess, "SendEventMessageToClient");
poolClient.Send(new {clientId = guid, message = "Hello to one client"}, "SendEventMessageToClient");
}
这里,我不需要TextArgs,可以使用它,但字符串也能正常工作。似乎转换为ITextArgs在这里工作正常。
public void SendEventMessageToAllClients(string message)
{
poolClient.Send("hello all", "SendEventMessageToAllClients");
}
控制器:仅映射ITextArgs消息。使用字符串不起作用。
public void SendEventMessageToClient(Guid clientId, ITextArgs message)
{
c.SendTo(p => p.ClientId == clientId, message.data, "events");
}
public void SendEventMessageToAllClients(ITextArgs message)
{
c.SendToAll(message.data, "events");
}
非常感谢Uffe的帮助!