Background
Due to the recent company to do small program chat, so .NetFramwork
version version SignalR
of the can not be used. Because there are no windows
objects in the applet, JQuery
it cannot be used. And Signalr
The JS client is dependent JQuery
.
So look at the core version of the SignarlR
test, found that can be run in, but the JS client to change to webscoekt
their own. If you need to change the version, you can comment downstairs.
Objective
The main purpose of this article is to introduce .NetCore
some of the pits used in the release SignalR
, and to provide a solution. Most of the previous articles were simply an introduction to the official demo. Not really put into use, some of these small problems are not digging deep and processing.
Cross-domain issues
.Net Frmawork
The version is simple, referencing the corresponding package, just add AddCores()
it, and the core version of the control is more accurate. ConfigureServices
Add the following code as follows
Services. Addcors (options = options. Addpolicy ("SignalR", + = { // allow arbitrary request mode / / Allow any header // to allow any Origin . Allowcredentials (); // Allow validation // // Specify a specific domain name to access }));
Then Configure
use the defined cross-domain policy
App. Usecors ("SignalR");
Using Redis scale Out
and .Net Framwork
the same,. The Netcore version SignalR
can use Redis to communicate between multiple servers. However, if the Redis is not connected successfully, the program will not error, but the communication will not work properly. and .Net Framwork
SignalR
The version of the words, the address directly 404.
So I want to monitor if Redis is connected successfully at boot time. But SignalR
the official documentation is simple to use, even Redis
how to configure it. So you can only go to the biggest dating site to find. A turn to see issue, finally found how to monitor.
Poke me at the details
To configure it with the following code, you can monitor Redis
if the connection is successful.
Services. ADDSIGNALR (). Addmessagepackprotocol (). Addredis (o={o.connectionfactory=Asyncwriter = { varConfig =Newconfigurationoptions {abortonconnectfail=false }; Config. Endpoints.add (Ipaddress.loopback,0); Config. Setdefaultports (); varConnection =awaitconnectionmultiplexer.connectasync (config, writer); Connection. Connectionfailed+ = (_, e) = ={Console.WriteLine ("Connection Redis failed."); }; if(!connection. isconnected) {Console.WriteLine ("Connection did not connect."); } returnconnection; }; });
But found in this way, Redis
connected 2 times, according to reason should not amount. Plus I have a lot of things to study source code. So just ask the author directly in this issue. We haven't found the reason yet. See the link above for details.
WebSocket Load Balancing Configuration
If you use load balancing to forward requests, you need a special configuration for WebSocket requests.
Find the operation of the classmate configuration, after the configuration to tell me that this SINGLLR communication address can only get request, cannot post request. Manual Black question mark ...
Such words can only be used in WebSocket
a LongPollin
way SSE
, like and the agreement can not be used.
I'm going to, like, a hole? So let ops to send me the configuration code, as follows
Proxy_http_version 1.1;p roxy_set_header Host $host;p roxy_set_header Upgrade $http _ Upgrade;proxy_set_header "upgrade";p roxy_connect_timeout - ;p roxy_read_timeout - ;p roxy_send_timeout ;
So I publish the app to a local virtual machine and run it in a docker
way. Then write the configuration into the Nginx configuration file.
The discovery really does not make a POST request and returns 400
. 400
the idea of a think request exception. There must be a problem with this configuration. So go to dating site to find issue, and sure enough to let me find. In a issue, the configuration provided is as follows
Proxy_http_version 1.1;p roxy_set_header Upgrade $http _upgrade;proxy_set_header Connection $ Http_connection;
The difference is proxy_set_header Connection
, did not write dead, so I changed the configuration, and really good.
proxy_set_header Connection
can not write dead, to get from the request header. There is no problem with other requests.
ConnectionID get
In the JS
client code, no more ConnectionID are provided. That is, if you want to use, you need to change the source Add. It's no problem, but Microsoft's big God shouldn't make such a low-level mistake. ConnectionId
when the negotiate
request is clear, why not open it? Is it a bug? There shouldn't be such a low-level bug.
So went to see issues, sure enough, there are also people asked, the author also has an explanation.
Go to dating sites and see
The general meaning is the use of the ConnectonId
server side, the client should not use this uncontrolled way to communicate. can be used Group
or User
this controllable way of communication, and there are examples given.
Here, in the use of the .Net Framwork
version, our site is used ConnectionId
to communicate, often the re-connection caused ConnectionId
by the change, and thus communication failure.
So I also adjusted the next design ideas, use Group
to communicate.
All of the above has been done, hard so long, according to reason should be no problem! Then release online!
The big Pit is here.
Apply my local test everything is OK, the test machine is not a problem, and then sent to the production environment, the results of the problem arises.
Because both local and test environments are single servers, testing is fine. and to the production environment, the server has more than one. No matter how I js set, always after the negotiate
request is executed, the next connection request must be 404, and return No Connection with that Id
.
Such as
See this error, the first reaction, my idea is Redis
not connected to success, so only a single run? So I was on top of the Redis code with a variety of monitoring, found that the connection was successful. Code review N-Times code, there is no place to change.
So the official documents went through. Finally found that JS can be configured in the following
New Signalr.hubconnectionbuilder () . Withurl ("/myhub", { true, Transport: SignalR.HttpTransportType.WebSockets }); . Build ();
The above code means skipping the negotiate
handshake and using WebSocket
the connection directly.
According to the document configuration, I go, really can. A communication connection was established because only one request was sent.
I am not calm now, can only deploy a server? How is stability guaranteed? This is still used in the small program (JS client has been modified), the low version can not be used websocket, is the lower version of it? How does the flow of the machine resist the live? Do you want to change your plan to make a communication?
No way, only big strokes. The source clone down, took a little time to read the next, find the following code
Private Async TaskGetconnectionasync (HttpContext context) {varConnectionID =GetConnectionID (context); if(Stringvalues.isnullorempty (ConnectionID)) {//there ' s no connection Id:bad requestContext. Response.statuscode =statuscodes.status400badrequest; Context. Response.ContentType= "Text/plain"; Await the context. Response.writeasync ("Connection ID Required"); return NULL; } if(!_manager. Trygetconnection (ConnectionID, outvarconnection)) { //No connection with that Id:not FoundContext. Response.statuscode =Statuscodes.status404notfound; Context. Response.ContentType= "Text/plain"; Await the context. Response.writeasync ("No Connection with that ID"); return NULL; } returnConnection;}
What does this piece of code mean? If connection didn't find it locally, it would return 404!
I go, is it a code bug?
Add some extra.
In the .Net Framwork
version, the source code will be ConnectionId
verified. Validation passes, but if connection is not found locally, a new connection is created to enable communication between multiple servers. So I have the above question. However, the disadvantage is that it is impossible to monitor when the client disconnects.
So I mentioned a issue and asked the author. poke me at the details
The reply Received is
It ' s not a bug it's by design. The ASP . NET Core SignalR requires sticky sessions when the using scale is out. This means your need to pin a connection to a particular serve
What do you mean? This is not a bug, that's how it's designed. SignalR
when used, the session is persisted and the request falls to the same server. This is more stable and can also monitor the client situation in real time.
So find the operation of the students in the load configured under the next session to keep, test again, finally can.
Summarize
In the process of this use SignalR
, encountered too many pits. It took a few hours to sort it out and record it and share it with you. Hope to help those who are prepared or have plans to use. Net core. Neter
Cgyqu
Source: www.cnblogs.com/cgyqu/p/9563193.html
This site uses the "Attribution 4.0 International" Creative sharing agreement, please indicate the author and source in the obvious position of the article.