I'm trying to connect with signalr hub, but I'm getting the following error in javascript:
WebSocket connection to 'ws://dev:777/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=%2BRUC9XodaU4R3Wn3BSLfhZXxLqeLj9fp4XlLJSsxrc36dFuEo6O9GOIGYMdsgSeswY2DTzzJe9qCe9JnqgjwusbYROxjkY%2B6d9FD4MVpox4FLEqNzCF5Y%2BOqrY5ndNs%2FRl7aOoKIYelpGmerXj4mdw%3D%3D&connectionData=%5B%7B%22name%22%3A%22machinehub%22%7D%5D&tid=5' failed: Error during WebSocket handshake: Unexpected response code: 504
and then in console
Could not connect. Invocation of StartMachine failed. Error: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.
I'm using such code to invoke my method from hub which:
self.Run = function (action, parameters, callbacks) {
try {
var connection = $.hubConnection();
connection.logging = self.Debug;
var hub = connection.createHubProxy(self.Name);
registerConnectionEvents(connection);
registerEvents(hub, callbacks);
connection.start({ transport: ['webSockets'] })
.done(function () {
self.debug("Now connected!");
hub.invoke.apply(hub, $.merge([action], parameters)).fail(function (error) {
var msg = 'Invocation of ' + action + ' failed. ' + error;
self.debug(msg);
});
})
.fail(function (error) {
var msg = 'Could not connect. Invocation of ' + action + ' failed. ' + error;
self.debug(msg);
});
return true;
}
When I run my MVC5 app with signalr in Visual Studio everything is fine. After publication to IIS8 on windows Server 2012 it can't connect over web sockets in signal r. I tried to turn off both firewalls for testing but with no success. Can you help me resolve that issue? Of course I read everthing on that page https://learn.microsoft.com/en-us/aspnet/signalr/
In order for SignalR to work properly with WebSocket, you must be sure both client and server support WebSocket. If testing locally works fine, then your browser probably already supports it.
Windows Server 2012 supports SignalR, but you need to be sure websockets feature is enabled:
If this is already enabled, then try recycling your Application Pool (or resetting the IIS).
If recycling/resetting is not sufficient, then you might have something else between the server and the client, like a proxy server or another security layer, like a network firewall (which you might don't have access to it), it could exist in an enterprise environment, or in servers hosted in places like Amazon which might be blocking a port.
Related
I'm trying to connect to a WAMP websocket server using Python and subscribe to receive messages, but I'm not able to achieve it. I have managed to connect using Autobahn on JS with this code:
< script src = "autobahn.js" > < /script> <script >
var conn = new ab.Session('ws://examplehost.com:8443/ws',
function() {
conn.subscribe('channel', function(topic, data) {
console.log(data);
alert('New data arrived: "' + topic + '" : ' + data.title);});},
function() {
console.warn('WebSocket connection closed');
}, {'skipSubprotocolCheck': true});
</script>
But using the same library on Python with below code results on 404 error:
from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner
class Component(ApplicationSession):
async def onJoin(self, details):
def on_event(i):
print("New data arrived: {}".format(i))
await self.subscribe(on_event, 'channel')
if __name__ == '__main__':
url = "ws://examplehost.com:8443/ws"
runner = ApplicationRunner(url)
runner.run(Component)
And this is the error I get:
failing WebSocket opening handshake ('WebSocket connection upgrade failed (404 - NotFound)')
dropping connection to peer tcp4:123.123.123.123:8443 with abort=True: WebSocket connection upgrade failed (404 - NotFound)
Any idea on how to solve this? After searching a lot maybe using the path /ws on the server is causing some issues, but I'm not sure. I have also tried with many other Python modules, but not luck.
This looks like a webserver issue. My understanding is websockets are created by upgrading reglar HTTP connections.
You need to configure the web server, and any proxy in the middle, to upgrade the configuration.
I've mostly encountered this with nginx. This looks like a good example.
I'm very new to Socket protocol and I'm sure the problem comes from me knowing almost nothing about this. But basically I have a socket on port 5000 on my server and I need to have an angularjs code to listen to this socket. The socket on the server can read whatever I send from another computer (client). But for some reason the angular code can't listen/connect to the socket. Here's what I have right now:
index.html
<html ng-app="MyAwesomeApp">
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/ng-websocket/ng-websocket.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="cnt">
</body>
</html>
and here's the angularjs code:
app.js
var app = angular.module('MyAwesomeApp', ['ngWebsocket']);
app.controller('cnt', function ($websocket) {
var ws = $websocket.$new('ws://localhost:5000');
ws.$on('$open', function () {
ws.$emit('hello', 'world'); // it sends the event 'hello' with data 'world'
})
.$on('test', function (message) { // it listents for 'incoming event'
console.log('something incoming from the server: ' + message);
});
});
and here's the python code that I have for server socket:
#server example
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 5000))
serversocket.listen(1) # become a server socket, maximum 5 connections
# print "hello"
while True:
connection, address = serversocket.accept()
print address
while True:
buf = connection.recv(16)
if len(buf) > 0:
connection.sendall(buf)
print buf
# break
Most of the angularjs code comes from https://coderwall.com/p/uhqeqg/html5-websocket-with-angularjs
These are the errors that I get in Chrome
ng-websocket.js:122 WebSocket connection to 'ws://localhost:5000/'
failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
and in Firefox:
Firefox can’t establish a connection to the server at
ws://localhost:5000/.
What you are trying to do is not possible. At least not in a way you want to do it.
WebSockets is an application layer protocol, much like HTTP protocol is. Pay attention at ws part of ws://localhost:5000.
On the other side you are using plain BSD sockets. This is just a raw socket for communication between two parties. It needs an to 'have an idea' about what the other side (AngularJS) is 'speaking', i.e. needs to communicate using same protocol. In BSD sockets case it inherently doesn't.
That is why you get:
ng-websocket.js:122 WebSocket connection to 'ws://localhost:5000/'
failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
To be able to do this, you will need some asynchronous programming framework with WebSockets protocol built on top of it. One suggestion is Autobahn.
I am doing a Chrome Application using the new Socket API (Chrome.sockets.tcp). I have been able to successfully get all HTTP requests working without any issue. The problem that I have run into is the HTTPS login with TLS handshake. We created a Visual Studio C# (RestRequest) application. We are able to connect using HTTPS. Using Wireshark, I notice that the successful communication was achieved using the TLSv1.
I have tried a variety of solutions and referenced/experimented with the below links and tried to come up with a solution.
https://groups.google.com/a/chromium.org/forum/#!msg/net-dev/U2ecAARKvAg/WI1WrSlaOPMJ
SSL Client Authentication with Certificate in Chrome App
Plus many more links! I have written a pile of test applications, but all reach a dead end after the initial handshake.
The following code sequence seems to get the handshake done, but I cannot send the login post. It seems as though the socket is messed up after the handshake. (WireShark shows all com’s were successful up until the login post).
var that = this;
chrome.sockets.tcp.create({
persistent: false,
name: "hc",
bufferSize: 8192
}, function (createInfo) {
console.log("create info = " + JSON.stringify(createInfo));
if (chrome.runtime.lastError) {
error('Unable to create socket: ' + chrome.runtime.lastError.message);
}
that._socketId = createInfo.socketId;
chrome.sockets.tcp.setPaused(that._socketId, true, function () {
chrome.sockets.tcp.connect(that._socketId, that._httpHost, that._httpPort, function (result) {
chrome.sockets.tcp.onReceive.addListener(that._onReceive.bind(this));
chrome.sockets.tcp.onReceiveError.addListener(that._onReceiveError.bind(this));
chrome.sockets.tcp.secure(that._socketId, function (secureResult) {
chrome.sockets.tcp.send(that._socketId, str2ab('POST / HTTP/1.1\r\nHOST: ' + that._httpHost + '\r\n\r\n'), function (sendResult) {});
});
});
});
});
I have tried implementing the TLSSocket from nmp forge and I get the same result as the example above.
We have to use TCP for this application, mainly for cookie support in a Chrome App.
Does anybody have a solution or suggestion? We have put in a lot of hours with trial and error, and seems like we have hit a dead end.
You need to unpause the socket after it's secured. e.g. chrome.sockets.tcp.setPaused(that._socketId, false, ...)
I want to provide a meaningful error to the client when too many users are connected or when they're connecting from an unsupported domain, so...
I wrote some WebSocket server code:
var http = require('http');
var httpServer = http.createServer(function (request, response)
{
// i see this if i hit http://localhost:8001/
response.end('go away');
});
httpServer.listen(8001);
// https://github.com/Worlize/WebSocket-Node/wiki/Documentation
var webSocket = require('websocket');
var webSocketServer = new webSocket.server({ 'httpServer': httpServer });
webSocketServer.on('request', function (request)
{
var connection = request.reject(102, 'gtfo');
});
And some WebSocket client code:
var connection = new WebSocket('ws://127.0.0.1:8001');
connection.onopen = function (openEvent)
{
alert('onopen');
console.log(openEvent);
};
connection.onclose = function (closeEvent)
{
alert('onclose');
console.log(closeEvent);
}
connection.onerror = function (errorEvent)
{
alert('onerror');
console.log(errorEvent);
};
connection.onmessage = function (messageEvent)
{
alert('onmessage');
console.log(messageEvent);
};
All I get is alert('onclose'); with a CloseEvent object logged to the console without any status code or message that I can find. When I connect via ws://localhost:8001 the httpServer callback doesn't come into play, so I can't catch it there. The RFC suggests I should be able to send any status code other than 101 when there's a problem, but Chrome throws an error in the console Unexpected response code: 102. If I call request.reject(101, 'gtfo'), implying it was successful I get a handshake error, as I'd expect.
Not really sure what else I can do. Is it just not possible right now to get the server response in Chrome's WebSocket implementation?
ETA: Here's a really nasty hack in the mean time, I hope that's not what I have to end up doing.
var connection = request.accept(null, request.origin);
connection.sendUTF('gtfo');
connection.close();
I'm the author of WebSocket-Node and I've also posted this response to the corresponding issue on GitHub: https://github.com/Worlize/WebSocket-Node/issues/46
Unfortunately, the WebSocket protocol does not provide any specific mechanism for providing a close code or reason at this stage when rejecting a client connection. The rejection is in the form of an HTTP response with an HTTP status of something like 40x or 50x. The spec allows for this but does not define a specific way that the client should attempt to divine any specific error messaging from such a response.
In reality, connections should be rejected at this stage only when you are rejecting a user from a disallowed origin (i.e. someone from another website is trying to connect users to your websocket server without permission) or when a user otherwise does not have permission to connect (i.e. they are not logged in). The latter case should be handled by other code on your site: a user should not be able to attempt to connect the websocket connection if they are not logged in.
The code and reason that WebSocket-Node allow you to specify here are an HTTP Status code (e.g. 404, 500, etc.) and a reason to include as a non-standard "X-WebSocket-Reject-Reason" HTTP header in the response. It is mostly useful when analyzing the connection with a packet sniffer, such as WireShark. No browser has any facility for providing rejection codes or reasons to the client-side JavaScript code when a connection is rejected in this way, because it's not provided for in the WebSocket specification.
I'm doing a simple UDP "send" using Node's inbuilt datagram UDP socket :
http://nodejs.org/docs/v0.3.1/api/dgram.html
The destination of the message is a domain name that has to be resolved by DNS before transmission.. node.js handles this.
In the event that DNS resolution fails dgram throws a "ENOTFOUND Domain Not Found" error and passes it to the callback that I've registered.
My code is like this:
client = dgram.createSocket("udp4");
client.send(message,
0,
message.length,
this.port,
this.address,
function(err, bytes) {
if (err) {
//get rid of error??
}
}
);
client.close();
I'm not particularly interested in the error.. if it fails, it fails, its not important to the business rules of the application. I'll log it to console for completeness.. BUT I cant stop this exception walking back up the stack and bringing down the application. How do I handle this error?
I dont wish to put a global uhandled exception handler in place just for this. I've tried rethrowing the error inside the callback within a Try/Except handler.. that didn't work.
Any thoughts?
Thanks for reading.
You need to listen for an error event from the socket. If you don't, then node will convert this to an exception. Do not try to handle this with uncaughtException, because the only safe thing to do from uncaughtException is log then exit.
Here is an example of listening for error and causing an intentional DNS error:
var dgram = require('dgram');
var message = new Buffer("Some bytes");
var client = dgram.createSocket("udp4");
client.on("error", function (err) {
console.log("Socket error: " + err);
});
client.send(message, 0, message.length, 41234, "1.2.3.4.5");
This should print:
Socket error: Error: ENOTFOUND, Domain name not found
And the program will continue running.