Теперь у меня есть следующее решение.Может кто-нибудь проверить мой код, если это распространенный способ, или у меня возникнут какие-то проблемы?
Сначала я создал концентраторный класс "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());
}
}
Затем я создал backgoundjob с Quartz.net "BackGroundJob.cs" (этот будет запускаться каждую секунду из класса JobScheduler после запуска приложения).Если доступны новые данные датчика, я отправляю данные датчика в определенную группу (имя группы будет создано после того, как клиент вызовет HubMethodName «registerName». Поскольку данные датчика № 6 следует отправлять только клиенту № 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. my 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);
}
})()