现在我有以下解决方案。如果这是一种常见的方式,有人可以检查我的代码吗?或者我会遇到麻烦吗?
首先我创建了一个集线器类“MyHub.cs”
我必须使用延迟初始化吗?
OnReconnected 部分可以吗?
[HubName("data")]
public class DataHub : Hub
{
List<LineUser> userList = new List<LineUser>();
public static ConcurrentDictionary<string, LineUser> MyUsers = new ConcurrentDictionary<string, LineUser>();
public override Task OnConnected()
{
var context = GlobalHost.ConnectionManager.GetHubContext<DataHub>();
string userConnectionID = Context.ConnectionId;
MyUsers.TryAdd(Context.ConnectionId, new LineUser() { ConnectionID = Context.ConnectionId });
return base.OnConnected();
}
public override Task OnReconnected()
{
var context = GlobalHost.ConnectionManager.GetHubContext<DataHub>();
string userConnectionID = Context.ConnectionId;
if (MyUsers.TryAdd(Context.ConnectionId, new LineUser() { ConnectionID = Context.ConnectionId }))
_userCount++;
var resconnectedUser = new LineUser();
MyUsers.TryGetValue(userConnectionID, out resconnectedUser);
Groups.Add(userConnectionID, resconnectedUser.LineNr.ToString());
return base.OnReconnected();
}
public override Task OnDisconnected(bool stopCalled)
{
var context = GlobalHost.ConnectionManager.GetHubContext<DataHub>();
string userConnectionID = Context.ConnectionId;
LineUser garbage;
var disconnectedUser = new LineUser();
MyUsers.TryGetValue(userConnectionID, out disconnectedUser);
Groups.Remove(userConnectionID, disconnectedUser.LineNr.ToString());
MyUsers.TryRemove(userConnectionID, out garbage);
return base.OnDisconnected(stopCalled);
}
[HubMethodName("registerName")]
public void RegisterConId(int LineNr, string userConnectionID)
{
var oldUser = new LineUser();
var newUser = new LineUser();
newUser.LineNr = LineNr;
newUser.ConnectionID = userConnectionID;
newUser.Connected = true;
MyUsers.TryGetValue(userConnectionID, out oldUser);
MyUsers.TryUpdate(userConnectionID, newUser, oldUser);
Groups.Add(userConnectionID, LineNr.ToString());
}
}
然后我用 Quartz.net "BackGroundJob.cs" 创建了一个 backgoundjob
(这将在应用程序启动后每秒从 JobScheduler 类触发)。
如果有新的传感器数据可用,我将传感器数据发送到特定组(组名将在客户端调用 HubMethodName“registerName”后创建。
因为传感器编号。 6 数据应该只发送给客户端 nr。 6(编号为 6 的所有客户端都在组“6”中)
public class BackGroundJob : IJob
{
//Global variable to save the result between to background job executions
SensorData oldsensorData = new SensorData();
public Task Execute(IJobExecutionContext context)
{
var newSensorData = ReadSensorData();
if (!newSensorData.Equals(oldsensorData))
{
IHubContext hub = GlobalHost.ConnectionManager.GetHubContext<DataHub>();
result = hub.Clients.Group(newSensorData.LineNr.ToString()).announceToLine("Sensor data for Line: " + newSensorData.LineNr.ToString() + " Temp: " + newSensorData.Temp.ToString());
//Save new data to global object
oldsensorData = newSensorData;
}
throw new NotImplementedException();
}
private SensorData ReadSensorData()
{
SensorData newSensorData = new SensorData();
//Code block to read sensor data from external device and save it to "newSensorData" object
return newSensorData;
}
}
我的客户端视图如下所示:
1. LineData.cshtml
@{
ViewBag.Title = "Line Data";
}
<h1>Linie: @ViewBag.LineNr</h1>
<h2>Temperature</h2>
<div id="sensorData"></div>
@section scripts{
<script>
var LineNr = parseInt(@ViewBag.LineNr);
</script>
<script src="~/signalr/js"></script>
<script src="~/Scripts/my/SignalR.js"></script>
}
和 2. 我的 SignalR.js
(function () {
var myHub = $.connection.data;
// start hub connection
$.connection.hub.start()
.done(function () {
//Register line number for group name
myHub.server.registerName(LineNr, $.connection.hub.id);
})
.fail(function () {
alert("SignalR Error for Line " + LineNr + " !");
});
// try reconnect after 5s
$.connection.hub.disconnected(function () {
setTimeout(function () {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
// Clients functions
myHub.client.announceToLine = function (data) {
$("#sensorData").html(data);
}
})()