SignalR 2.2 and ARR3.0 Load balancing

2019-02-25 12:28发布

问题:

I am using signalr2.2 web application and hosted in IIS-8. Here I tried to implement load balancing for my application using ARR3.0. In my server farm I connected two servers and set the routing rule as 'weighted round robin'. Every server has a javascript client with HTML page. While I am accessing HTML page of any server the request has been routed as expected but I am having this error in my html page and signalr doesn't get connected

WebSocket connection to 'ws://mydomain.com/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=x9rAfatyMm3TbqzrYKL1K37Z4tKrUTH7bwNmSItW55Z0ms6pe43YiQGFOmaHMyT%2BpmGz62ukt4tha72vPcJhdqLtIvsQvqvY15oYGv69JjzSuuiSL7v2l%2FccZT6tQa3Z&connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&tid=1' failed: Error during WebSocket handshake: Unexpected response code: 400

If I make offline anyone of this server in my serverfarm, signalr worked fine and no errors will thrown. Help me to find the solution.

If I communicate signalr server from my .net client application it will throw the following error

Error during start request. Stopping the connection.

回答1:

I had this problem as well. Looking deeper, the error is: The connection id is in the incorrect format. After googling a bit, I read somewhere that when running a farm environment, the servers need to share the same machine key, which can be configured in IIS.

To this, follow these steps:

  • Open the IIS connecting to any of your servers in the farm.
  • In the server node, open the Machine Key option in the right pane
  • In the right menu, click Generate Keys
  • Uncheck the Generate a unique key for each application option for both Validation key and Decryption key.
  • Copy the two keys generated (e.g paste in notepad)
  • Make sure all servers in the farm share this same keys (the ARR server doesn't need this), you might need to repeat the steps above in them (maybe you don't as soon as they use Shared Configuration).

Also, you need to make sure your application in each server use the same Identity. For example, select your application node (or site node if it's the case), in right menu select Basic Settings, then Connect as.... If the selected option is Application user, then you need to check how is your Application Pool configured. If it uses Network Service (as were mine), you'll still have problems, because each server uses its own credentials, but you have to make sure they use the same Identity.

In my scenario, I had to create a user with access to every server in the farm, and make the application use this same user. Only after doing this my problem was solved.



回答2:

In addition to @Alisson's answer I found an easy way for setting Machine Key.

You can directly do this setting in your Web.config file. Simple create an entry for machineKey under system.web section. The entry will look like

<system.web>   
    <machineKey validationKey="###############YOUR#####VALIDATION ######KEY####################################################################################" decryptionKey="#####YOUR####DECRYPTION#####KEY#################" validation="SHA1" decryption="Auto" />
</system.web>

A unique Validation key and Decryption key can be generated by steps given in @Alisson's answer.

By using this approach you don't need to worry about your server change at any point or deployment at any other web farm server. Your code will run without any issues.