I have this code in console application.
I am trying to connect from dev tools chrome, but get this error although the problem is for sure in WCF side:
WebSocket connection to 'wss://127.0.0.1:5650/Echo' failed: Error in connection establishment: net::ERR_CONNECTION_RESET
WSS is not hitting my server code, no exceptions not even logs. WS with minimum modifications is working fine. I used the Microsoft.WebSockets from nuget to simplify code:
WebSocketHost server = new WebSocketHost(typeof(EchoWSService), new Uri("https://127.0.0.1:5650/Echo"));
var bindingSsl = WebSocketHost.CreateWebSocketBinding(true);
server.AddWebSocketEndpoint(bindingSsl);
server.Open();
I already tried a Custom Cert Validator, but as I said it is not hitting my code.
Now I have the same code except the server.Open() in a ASP.net app using ServiceRoute, and it is working pretty fine! yes with SSL and a self signed cert generated by VS for IIS express:
RouteTable.Routes.Add(new ServiceRoute("Echo", new TRWebSocketServiceFactory(), typeof(EchoWSService)));
The browser side only is:
var ws = new WebSocket('wss://127.0.0.1:5650/Echo')
In web.config I don't have more than
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
So why the hell is not working my self hosted WCF in a simple console app?
All right, finally I got this working with self signed cert and also with a cert issued by COMODO.
I investigated what IIS does and mimic that, it binds the port and host at OS level. I based this result in this codeproject post.
1. Install the certificate in the hosting machine.
For testing proposals I am using a self-signed certificate which was generated with VS for IIS. You can use another or make it yourself with makecert.exe. Install it in Personal→Certificates.
2. Secure the Socket. Over command line as Administrator run:
netsh http add sslcert ipport=0.0.0.0:5650 certhash=xxxxxxx.. appid={xxxx-xxx..} certstorename=MY
netsh http add sslcert hostnameport=domainnamne:5650 certhash=xxxxxxx.. appid={xxxx-xxx..} certstorename=MY
Where:
- ipport and hostnameport = Are the ip, host or domain and port bind to the certificate.
- certhash = Is the cert’s thumb print without spaces.
- appid = Is whatever GUID, it is supposed to identify what app is using it.
- certstorename = The path to the cert, in this case MY means Personal→Certificates
In Windows Server 2008, we can use *httpcfg.exe*** for same proposal.
Once it binds successful we can review by running:
netsh http show sslcert
We will get:
Hostname:port : domainname:5650
Certificate Hash : xxxxxxx..
Application ID : {xxxx-xxx..}
Certificate Store Name : MY
Verify Client Certificate Revocation : Enabled
…
3. Accept the cert in browser side. This step is not needed if we have a valid trusted certificate.
So to make the browser accept the cert, navigate to https://domainname:5650 (domain name must match the one you used to bind in step 2)
Then we get the dialog to accept the cert, in chrome maybe needed to navigate to https://domainname:5650/Service.
And Voila, in console you can try:
ws = new WebSocket('wss://domainname:5650/Service');
And no exceptions.