EDIT: Look at the bottom of this post for updates.
编辑:请查看此帖子的底部以获取更新。
My SignalR implementation works perfectly on my local system. But when I deployed it out to my server it doesnt seem to work. Its an MVC project.
我的SignalR实现在我的本地系统上完美运行。但是当我将它部署到我的服务器时,它似乎无法工作。它是一个MVC项目。
My signalR jQuery is as follows:
我的signalR jQuery如下:
var clientHub = $.connection.gamehub;
$(function () {
var signalRHubInitialized = false;
var image = $("#Ico");
var count = 0;
initializeSignalRHubStore();
function initializeSignalRHubStore() {
if (signalRHubInitialized)
return;
try {
clientHub.client.broadcastMessage = function (message) {
if (message === "Refresh")
reloadIndexPartial();
};
$.connection.hub.start().done(function () {
clientHub.server.initialize($("#NotifierEntity").val());
signalRHubInitialized = true;
});
} catch (err) {
signalRHubInitialized = false;
}
};
function reloadIndexPartial() {
//$.post('@(Url.Action("LivePartial", "Scrim", null, Request.Url.Scheme))')
var id = $("#SeriesDetail_Id").val();
$.post('/Scrim/LivePartial/' + id)
.done(function (response) {
try {
count = count + 1;
var favicon = new Favico({
animation: 'pop',
image: image
});
favicon.badge(count);
}
catch (exception) {
}
$("#summary-wrapper").html("");
$("#summary-wrapper").html(response);
if (!signalRHubInitialized)
initializeSignalRHubStore();
});
};
});
I downloaded Fiddler to see what was going on:
我下载了Fiddler,看看发生了什么:
/signalr/hubs returned a HTTP200
/ signalr / hubs返回了HTTP200
GET http://sitename.com/signalr/hubs HTTP/1.1
Host: sitename.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Accept: */*
Referer: http://sitename.com/scrim/Live/2835
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: _gat=1; _ga=GA1.2.1342148401.1475084375; _gid=GA1.2.2092796788.1503865866
negotiate returned at HTTP200
谈判在HTTP200返回
GET http://sitename.com/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22gamehub%22%7D%5D&_=1505151041506 HTTP/1.1
Host: sitename.com
Connection: keep-alive
Accept: text/plain, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Content-Type: application/json; charset=UTF-8
Referer: http://sitename.com/scrim/Live/2835
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: _gat=1; _ga=GA1.2.1342148401.1475084375; _gid=GA1.2.2092796788.1503865866
connect, didnt return anything
连接,没有返回任何东西
GET http://sitename.com/signalr/connect?transport=serverSentEvents&clientProtocol=1.5&connectionToken=S8rqz2NPvVSJxbS1%2FpLm7yHTinGHWK1SnAwh8IfYA%2BP7nVb9RV%2FJzSFsf8Q%2BTv6Z%2Fae%2FIoZKlHKyeTxaEn3obg%2FVViYTB5HZxnrvKvtBZtQopvGPdj1i4o8Z9wGlCz3%2F&connectionData=%5B%7B%22name%22%3A%22gamehub%22%7D%5D&tid=10 HTTP/1.1
Host: sitename.com
Connection: keep-alive
Accept: text/event-stream
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Referer: http://sitename.com/scrim/Live/2835
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: _gat=1; _ga=GA1.2.1342148401.1475084375; _gid=GA1.2.2092796788.1503865866
start returned a HTTP200
开始返回HTTP200
GET http://sitename.com/signalr/start?transport=serverSentEvents&clientProtocol=1.5&connectionToken=S8rqz2NPvVSJxbS1%2FpLm7yHTinGHWK1SnAwh8IfYA%2BP7nVb9RV%2FJzSFsf8Q%2BTv6Z%2Fae%2FIoZKlHKyeTxaEn3obg%2FVViYTB5HZxnrvKvtBZtQopvGPdj1i4o8Z9wGlCz3%2F&connectionData=%5B%7B%22name%22%3A%22gamehub%22%7D%5D&_=1505151041507 HTTP/1.1
Host: sitename.com
Connection: keep-alive
Accept: text/plain, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Content-Type: application/json; charset=UTF-8
Referer: http://sitename.com/scrim/Live/2835
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: _gat=1; _ga=GA1.2.1342148401.1475084375; _gid=GA1.2.2092796788.1503865866
Send returned a HTTP200
发送返回HTTP200
POST http://sitename.com/signalr/send?transport=serverSentEvents&clientProtocol=1.5&connectionToken=S8rqz2NPvVSJxbS1%2FpLm7yHTinGHWK1SnAwh8IfYA%2BP7nVb9RV%2FJzSFsf8Q%2BTv6Z%2Fae%2FIoZKlHKyeTxaEn3obg%2FVViYTB5HZxnrvKvtBZtQopvGPdj1i4o8Z9wGlCz3%2F&connectionData=%5B%7B%22name%22%3A%22gamehub%22%7D%5D HTTP/1.1
Host: sitename.com
Connection: keep-alive
Content-Length: 2227
Accept: text/plain, */*; q=0.01
Origin: http://sitename.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://sitename.com/scrim/Live/2835
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: _gat=1; _ga=GA1.2.1342148401.1475084375; _gid=GA1.2.2092796788.1503865866
data=%7B%22H%22%3A%22gamehub%22%2C%22M%22%3A%22Initialize%22%2C%22A%22%3A%5B%22%7B%5C%22SqlQuery%5C%22%3A%5C%22SELECT+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BId%5D+AS+%5BId%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BGameGuid%5D+AS+%5BGameGuid%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BDate%5D+AS+%5BDate%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BTeamOneScore%5D+AS+%5BTeamOneScore%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BTeamZeroScore%5D+AS+%5BTeamZeroScore%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BTeamOneId%5D+AS+%5BTeamOneId%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BTeamZeroId%5D+AS+%5BTeamZeroId%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BGameVariantId%5D+AS+%5BGameVariantId%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BMapId%5D+AS+%5BMapId%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BDuration%5D+AS+%5BDuration%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BSeriesId%5D+AS+%5BSeriesId%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BResult%5D+AS+%5BResult%5D%2C+%5C%5Cr%5C%5Cn++++%5BExtent1%5D.%5BActive%5D+AS+%5BActive%5D%5C%5Cr%5C%5Cn++++FROM+%5Bdbo%5D.%5BGame%5D+AS+%5BExtent1%5D%5C%5Cr%5C%5Cn++++WHERE+(%5BExtent1%5D.%5BActive%5D+%3D+1)+AND+(%5BExtent1%5D.%5BSeriesId%5D+%3D+%40p__linq__0)%5C%22%2C%5C%22SqlConnectionString%5C%22%3A%5C%22Data+Source%3DWIN-1J1JAEOEU33%3BInitial+Catalog%3DSiteName%3BIntegrated+Security%3DTrue%3BMultipleActiveResultSets%3DTrue%3B%5C%22%2C%5C%22SqlParameters%5C%22%3A%5B%7B%5C%22CompareInfo%5C%22%3A0%2C%5C%22XmlSchemaCollectionDatabase%5C%22%3A%5C%22%5C%22%2C%5C%22XmlSchemaCollectionOwningSchema%5C%22%3A%5C%22%5C%22%2C%5C%22XmlSchemaCollectionName%5C%22%3A%5C%22%5C%22%2C%5C%22DbType%5C%22%3A11%2C%5C%22LocaleId%5C%22%3A0%2C%5C%22ParameterName%5C%22%3A%5C%22p__linq__0%5C%22%2C%5C%22Precision%5C%22%3A0%2C%5C%22Scale%5C%22%3A0%2C%5C%22SqlDbType%5C%22%3A8%2C%5C%22SqlValue%5C%22%3A%7B%5C%22IsNull%5C%22%3Afalse%2C%5C%22Value%5C%22%3A2835%7D%2C%5C%22UdtTypeName%5C%22%3A%5C%22%5C%22%2C%5C%22TypeName%5C%22%3A%5C%22%5C%22%2C%5C%22Value%5C%22%3A2835%2C%5C%22Direction%5C%22%3A1%2C%5C%22IsNullable%5C%22%3Afalse%2C%5C%22Offset%5C%22%3A0%2C%5C%22Size%5C%22%3A0%2C%5C%22SourceColumn%5C%22%3A%5C%22%5C%22%2C%5C%22SourceColumnNullMapping%5C%22%3Afalse%2C%5C%22SourceVersion%5C%22%3A512%7D%5D%7D%22%5D%2C%22I%22%3A0%7D
I have added this to my web config:
我已将此添加到我的网络配置中:
<modules runAllManagedModulesForAllRequests="true"></modules>
Looking through all the responses it seems that everything is working correctly but the page Im on is not being updated when a new entry has been added to the database.
查看所有响应后,似乎一切正常,但是当新条目添加到数据库时,页面Im on不会更新。
On my local development system my project is set up using IIS it works flawlessly.
在我的本地开发系统上,我的项目是使用IIS设置的,它可以完美运行。
Could anyone point me in the right direction please.
任何人都可以指出我正确的方向。
EDIT: I have got it working on the server now. But it seems that it works right after it has been deployed for a few hours. Then after that it seems to stop working. So I have to assume that the signalr connection is being disposed at some stage and now getting reinstated?
编辑:我现在已经在服务器上工作了。但似乎它在部署几个小时之后才能正常工作。然后,它似乎停止工作。所以我必须假设信号器连接正在某个阶段处理,现在恢复了?
Here is my RegisterServices class:
这是我的RegisterServices类:
private static IContainer RegisterServices(ContainerBuilder builder)
{
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<ContextEntities>()
.As<DbContext>()
.InstancePerRequest();
builder.RegisterType<DbFactory>()
.As<IDbFactory>()
.InstancePerRequest();
builder.RegisterType<UnitOfWork>()
.As<IUnitOfWork>()
.InstancePerRequest();
// Services
builder.RegisterType<MembershipService>()
.As<IMembershipService>()
.InstancePerRequest();
builder.RegisterType<CacheService>()
.As<ICacheService>()
.InstancePerRequest();
builder.RegisterType<GameHub>().ExternallyOwned();
Container = builder.Build();
return Container;
}
Here is a page where signalr is used: http://halodatahive.com/Scrim/Live/2845
这是一个使用信号器的页面:http://halodatahive.com/Scrim/Live/2845
I seem to be losing reference to the signalr connection after a few hours after a deployment.
部署后几个小时后,我似乎失去了对signalr连接的引用。
EDIT: If I recycle my APP POOL the page with signalR starts working again.
编辑:如果我回收我的APP POOL,带有signalR的页面将重新开始工作。
3 个解决方案
#1
7
This is what I ended up using to resolve the issue. It seems that after around 1 hour it was getting disconnected some how. I put this code in a few hours ago and it still seems to be working. Thanks to @Noren for all their help in chat earlier!
这就是我最终用来解决问题的方法。似乎在大约1小时之后它会变得如此断断续续。我在几个小时之前就把这段代码放了,它似乎仍然有用。感谢@Noren之前在聊天中提供的所有帮助!
EDIT: This did not seem to solve the problem unfortunately.
编辑:不幸的是,这似乎没有解决问题。
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
EDIT: Thought I would give an update as to how I got this working. Instead of using SqlDependency
to trigger the SignalR I just called Clients.All.broadcastMessage("Refresh");
on the scheduled task I have running on the server when _unitOfWork.Commit()
was called.
编辑:我想我会更新我的工作方式。而不是使用SqlDependency来触发SignalR我刚刚调用了Clients.All.broadcastMessage(“Refresh”);在调用_unitOfWork.Commit()时我在服务器上运行的计划任务。
Something was causing SqlDependency to stop working and the only way to get it to pick it up again was to recycle the app pool.
有些事情导致SqlDependency停止工作,让它再次获取它的唯一方法是回收应用程序池。
#2
2
I've seen something like this before. In my case it was RabbitMQ events that were lost because IIS was spinning down the application.
我以前见过这样的东西。在我的情况下,由于IIS正在关闭应用程序,因此丢失了RabbitMQ事件。
Is your application is not being hit very frequently? IIS has a tendency to spin down applications that it doesn't think it needs in order to save resources. That might be why it only stops working after a few hours and you can recycle to bring it back up.
您的应用程序是不是经常被击中? IIS倾向于降低它认为不需要的应用程序以节省资源。这可能就是为什么它只能在几个小时后停止工作,你可以回收再来。
看到这个答案。
#3
2
first add Hubs folder and
NotificationsHubs.cs
in root首先在root中添加Hubs文件夹和NotificationsHubs.cs
in NotificationsHubs.cs
在NotificationsHubs.cs中
[HubName("NotificationsHubs")]
public class NotificationsHubs : Hub
{
public static Thread NotificationsThread;
public void Send(string token, string UserAgent, string IP)
{
var serverVars = Context.Request.GetHttpContext().Request.ServerVariables;
string SignalRIp = serverVars["REMOTE_ADDR"];
string T = Context.Request.Headers["User-Agent"].ToLower();
if ((T == cryptClass.crypt.Decrypt(UserAgent)) && (SignalRIp == cryptClass.crypt.Decrypt(IP)))
{
var connection = SignalRConnections.Connections.SingleOrDefault(c => c.Token == Guid.Parse(token));
if (connection != null)
{
connection.Context = this.Context;
}
if (NotificationsThread == null || !NotificationsThread.IsAlive)
{
NotificationsThread = new Thread(new ThreadStart(NotificationsCheck));
NotificationsThread.Start();
}
}
NotificationsCheck
is custom function
NotificationsCheck是自定义功能
in NotificationController
在NotificationController中
public ActionResult Notifications()
{
NotificationsModule.messageBL = _messageBL;
long UserID = GetCurrentUser();
Notification _Notification = new Notification();
_Notification.GetToken = SignalRConnections.GetToken(UserID);
_Notification.UserAgent = cryptClass.crypt.Encrypt(Request.UserAgent.ToLower());
_Notification.IP = cryptClass.crypt.Encrypt(Request.UserHostAddress);
return View(_Notification);
}
in Notifications.cshtml
view
在Notifications.cshtml视图中
add this JS file
添加这个JS文件
<script src="~/Scripts/jquery.signalR-2.2.1.js")"></script>
<script src="~/signalr/hubs"></script>
$(function () {
// Reference the auto-generated proxy for the hub.
var chat = $.connection.NotificationsHubs;
// Create a function that the hub can call back to display messages.
chat.client.addNewMessageToPage = function (Title, Body, Icon) {
// Add the message to the page.
notifyMe(Title, Body, Icon);
};
$.connection.hub.start().done(function () {
chat.server.send('@Model.GetToken', '@Model.UserAgent', '@Model.IP');
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send();
});
});
});
notifyMe(Title, Body, Icon);
is jquery custom function
notifyMe(标题,正文,图标);是jquery自定义功能
#1
7
This is what I ended up using to resolve the issue. It seems that after around 1 hour it was getting disconnected some how. I put this code in a few hours ago and it still seems to be working. Thanks to @Noren for all their help in chat earlier!
这就是我最终用来解决问题的方法。似乎在大约1小时之后它会变得如此断断续续。我在几个小时之前就把这段代码放了,它似乎仍然有用。感谢@Noren之前在聊天中提供的所有帮助!
EDIT: This did not seem to solve the problem unfortunately.
编辑:不幸的是,这似乎没有解决问题。
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
EDIT: Thought I would give an update as to how I got this working. Instead of using SqlDependency
to trigger the SignalR I just called Clients.All.broadcastMessage("Refresh");
on the scheduled task I have running on the server when _unitOfWork.Commit()
was called.
编辑:我想我会更新我的工作方式。而不是使用SqlDependency来触发SignalR我刚刚调用了Clients.All.broadcastMessage(“Refresh”);在调用_unitOfWork.Commit()时我在服务器上运行的计划任务。
Something was causing SqlDependency to stop working and the only way to get it to pick it up again was to recycle the app pool.
有些事情导致SqlDependency停止工作,让它再次获取它的唯一方法是回收应用程序池。
#2
2
I've seen something like this before. In my case it was RabbitMQ events that were lost because IIS was spinning down the application.
我以前见过这样的东西。在我的情况下,由于IIS正在关闭应用程序,因此丢失了RabbitMQ事件。
Is your application is not being hit very frequently? IIS has a tendency to spin down applications that it doesn't think it needs in order to save resources. That might be why it only stops working after a few hours and you can recycle to bring it back up.
您的应用程序是不是经常被击中? IIS倾向于降低它认为不需要的应用程序以节省资源。这可能就是为什么它只能在几个小时后停止工作,你可以回收再来。
看到这个答案。
#3
2
first add Hubs folder and
NotificationsHubs.cs
in root首先在root中添加Hubs文件夹和NotificationsHubs.cs
in NotificationsHubs.cs
在NotificationsHubs.cs中
[HubName("NotificationsHubs")]
public class NotificationsHubs : Hub
{
public static Thread NotificationsThread;
public void Send(string token, string UserAgent, string IP)
{
var serverVars = Context.Request.GetHttpContext().Request.ServerVariables;
string SignalRIp = serverVars["REMOTE_ADDR"];
string T = Context.Request.Headers["User-Agent"].ToLower();
if ((T == cryptClass.crypt.Decrypt(UserAgent)) && (SignalRIp == cryptClass.crypt.Decrypt(IP)))
{
var connection = SignalRConnections.Connections.SingleOrDefault(c => c.Token == Guid.Parse(token));
if (connection != null)
{
connection.Context = this.Context;
}
if (NotificationsThread == null || !NotificationsThread.IsAlive)
{
NotificationsThread = new Thread(new ThreadStart(NotificationsCheck));
NotificationsThread.Start();
}
}
NotificationsCheck
is custom function
NotificationsCheck是自定义功能
in NotificationController
在NotificationController中
public ActionResult Notifications()
{
NotificationsModule.messageBL = _messageBL;
long UserID = GetCurrentUser();
Notification _Notification = new Notification();
_Notification.GetToken = SignalRConnections.GetToken(UserID);
_Notification.UserAgent = cryptClass.crypt.Encrypt(Request.UserAgent.ToLower());
_Notification.IP = cryptClass.crypt.Encrypt(Request.UserHostAddress);
return View(_Notification);
}
in Notifications.cshtml
view
在Notifications.cshtml视图中
add this JS file
添加这个JS文件
<script src="~/Scripts/jquery.signalR-2.2.1.js")"></script>
<script src="~/signalr/hubs"></script>
$(function () {
// Reference the auto-generated proxy for the hub.
var chat = $.connection.NotificationsHubs;
// Create a function that the hub can call back to display messages.
chat.client.addNewMessageToPage = function (Title, Body, Icon) {
// Add the message to the page.
notifyMe(Title, Body, Icon);
};
$.connection.hub.start().done(function () {
chat.server.send('@Model.GetToken', '@Model.UserAgent', '@Model.IP');
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send();
});
});
});
notifyMe(Title, Body, Icon);
is jquery custom function
notifyMe(标题,正文,图标);是jquery自定义功能