【发布时间】:2019-12-24 02:05:13
【问题描述】:
我为 SignalR 设置了一个基本解决方案,我可以通过浏览器向所有客户端发送和接收消息。
所需的解决方案:
我需要实现组的使用,但能够加入组并从服务器上运行的后台服务类发送消息。
目前我只成功地从服务器向所有客户端发送了一条消息。
我的后台服务类(基本上是一个通信服务器)将运行多个实例,因此每个实例都有一个唯一的名称,例如 CommsServer 1、CommsServer 2 等。通信服务器的每个实例都需要将消息输出到特定的SignalR 接收者组。
在浏览器中,用户将从服务器拉出的下拉列表中选择他们希望加入的 SignalR 组。服务器也知道这个相同的列表,因此每个通信服务器实例将代表列表中的一个项目。
到目前为止我的代码:
MessageHub 类:
public class MessageHub : Hub
{
public Task SendMessageToAll(string message)
{
return Clients.All.SendAsync("ReceiveMessage", message);
}
}
Message.js 文件:
"use strict";
var connection = new signalR.HubConnectionBuilder()
.withUrl("/messages")
.build();
connection.on("ReceiveMessage", function (message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var div = document.createElement("div");
div.innerHTML = msg + "<hr/>";
document.getElementById("messages").appendChild(div);
});
connection.start().catch(function (err) {
return console.error(err.toString());
});
document.getElementById("sendButton").addEventListener("click", function (event) {
var message = document.getElementById("message").value;
connection.invoke("SendMessageToAll", message).catch(function (err) {
return console.error(err.toString());
});
e.preventDefault();
});
剃刀页面:
<textarea name="message" id="message"></textarea>
<input type="button" id="sendButton" value="Send Message" />
<div id="messages"></div>
<script src="~/lib/signalr/dist/browser/signalr.js"></script>
<script src="~/js/message.js"></script>
通讯服务器类:
public class TcpServer
{
private readonly IHubContext<MessageHub> _hubContext;
public TcpServerTcpServer(IHubContext<MessageHub> hubContext)
{
_hubContext = hubContext;
}
public string inboundIpAddress = "127.0.0.1";
public int inboundLocalPortNumber = 10001;
public void TcpServerIN(string serverName)
{
Task.Run(() =>
{
IPAddress localAddrIN = IPAddress.Parse(inboundIpAddress);
TcpListener listener = new TcpListener(localAddrIN, inboundLocalPortNumber);
listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream(); // Networkstream is used to send/receive messages
//Buffer for reading data
Byte[] bytes = new Byte[4096];
String data = null;
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
_hubContext.Clients.All.SendAsync(data);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, data.Length);
}
// Shutdown and end connection
client.Close();
}
});
}
}
我需要选择一个特定的 SignalR 组名称,例如“CommsServer 1”这将形成 SignalR 组的名称,用户可以从浏览器的下拉列表中选择该组,以便他们可以监视来自这个特定服务器实例的事件。其他用户可能希望监视来自不同服务器实例的事件。
我正在考虑的一个选项是简单地将事件从所有服务器实例发送到所有浏览器连接的客户端,然后以某种方式过滤客户端上的事件,但这似乎是一种低效的处理方式,不利于网络流量。
【问题讨论】:
标签: asp.net-core signalr