I am trying to host a websocket using node.js and it seems to host fine, but I cannot connect to it externally because I just get the error in the title. The : after failed suggests there should be extra details and similar questions here prove that, but I'm not getting anything after the colon making this very difficult to debug. I have tried in multiple browsers and I get the same error so it's not my browser causing this. My best guess would be that my cerificates aren't working, but they're the same certificates I use for the rest of my websites and they work fine for them so not too sure.
This is my server-side (node.js) code:
const server = require('https').createServer({
cert: fs.readFileSync('/etc/letsencrypt/live/mydomain.com/fullchain.pem'),
key: fs.readFileSync('/etc/letsencrypt/live/mydomain.com/privkey.pem')
});
const websocket = new (require('ws').Server)({server});
websocket.on('connection', (client, request) => {
console.log("New connection from "+request.socket.remoteAddress);
});
And my client-side (Javascript) code is just
new WebSocket("wss://mydomain.com:8080").onmessage = (event) => {
console.log(event.data);
};
I have tried making my node.js server listen to port 8080 but that made no difference. I have also tried different URLs on the client side (such as without the protocol, without the port, using my ip) but as I would expect, those don't work either.
Related
I'm very very new to sockets and socket.io, so I apologize if this is an obvious question. I'm using the C# client for Socket.IO and have a local javascript server running. Here is my app.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket) {
console.log('A user connected');
socket.on('test', function () {
console.log('Test run'); });
socket.on('disconnect', function () {
console.log('A user disconnected'); });
});
http.listen(3000, function() {
console.log('listening on localhost:3000'); });
In my main C# class (it is a Windows Forms application) the only line of code I have relating to the sockets at all is the instance variable private Socket socket = IO.Socket("http://localhost:3000/");. Yet for some reason, the server repeatedly receives the connect and disconnect events. Here is a screenshot of my console:
screenshot
This all happens automatically, as soon as I run my C# program, without any interaction, and stops as soon as I close it. Any ideas as to why it keeps connecting/disconnecting?
EDIT: For whatever reason the problem seems to go away when I remove Newtonsoft.json from the project. However, without it I cannot use the Emit function as well as others. Is there a workaround to this?
To anyone encountering this issue, check if client & server speak the same protocol version.
On a high-level, this is likely to be caused by protocol version mismatch between server and client. I've had the same issue in JS app. Turned out I was using some older version of socket.io on the client and the latest on the server. In the repository you provided we can find:
// EngineIoClientDotNet/Src/EngineIoClientDotNet.mono/Parser/Parser.cs
public static readonly int Protocol = 3;
So this (now deprecated) client is using Engine.IO protocol v3. You didn't provide info which socket.io version you were using on the server, but it simply might've been using different revision on Engine.IO protocol.
As a side note, speaking more low-level: I guess that the client might be able to connect, but it does not respond to server's first ping command in a proper way (or the other way around). Therefore the connection is immediately dropped. Socket.IO has a history of breaking changes in how ping-pong mechanism is implemented, and this might be the underlying root cause.
In Node.js, I have implemented a WebSocket server which is used by a smartphone app. In some cases I got this kind of error (Invalid WebSocket frame: RSV1 must be clear):
This kind of application is running on many different servers across the world, but have the problem only with one instance. The app crashes randomly when using the communication between smartphones (Android or IOS) but it did not crash if I try to send messages over WebSocket using Java.
Looking at the doc of WebSocket specification have found that:
Currently, I can't find what could be wrong. Do you think it could be some "network set-up issue"?
The libraries used for WebSocket in Node.js is ws 6.2.1.
The service is running inside a docker using alpine:8 image. As I told I have a problem only in one environment in all other environments everything works fine. Any idea what else to check?
Well in my case i was sending an object, when i JSON.stringify() it , it started working
For my case I put in return and it solves my issue:
Before:
if (pathname === "/foo/1") {
wss.handleUpgrade(request, socket, head, function done(ws) {
wss.emit("connection", ws, request);
});
}
After:
if (pathname === "/foo/1") {
wss.handleUpgrade(request, socket, head, function done(ws) {
wss.emit("connection", ws, request);
});
return;
}
I think the RSV1 bit can be related to compression setting. There is a similar question to yours ("Invalid WebSocket frame: RSV1 must be clear) here: "Error: Invalid WebSocket frame: RSV1 must be clear" while using Socket.IO
All you need to do is on the server side, pass on an option related to the
"Sec-WebSocket-Extensions: permessage-deflate;"
,
for example,
new Server({
perMessageDeflate {
...
}
});
I have a vb.net application that opens a socket and listens on it.
I need to communicate via this socket to that application using a javascript running on a browser. That is i need to send some data on this socket so that the app which is listening on this socket can take that data, do some stuff using some remote calls and get some more data and put it back on the socket that my javascript needs to read and print it in the browser.
Ive tried, socket.io, websockify but none have proved to be useful.
Hence the question, is what i am trying even possible? Is there a way that a javascript running in a browser can connect to a tcp socket and send some data and listen on it for some more data response on the socket and print it to the browser.
If this is possible can some one point me in the right direction as to which would help me establish the goal.
As for your problem, currently you will have to depend on XHR or websockets for this.
Currently no popular browser has implemented any such raw sockets api for javascript that lets you create and access raw sockets, but a draft for the implementation of raw sockets api in JavaScript is under-way. Have a look at these links:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket
Chrome now has support for raw TCP and UDP sockets in its ‘experimental’ APIs. These features are only available for chrome apps and, although documented, are hidden for the moment. Having said that, some developers are already creating interesting projects using it, such as this IRC client.
To access this API, you’ll need to enable the experimental flag in your extension’s manifest. Using sockets is pretty straightforward, for example:
chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");
});
});
This will be possible via the navigator interface as shown below:
navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
() => {
// Permission was granted
// Create a new TCP client socket and connect to remote host
var mySocket = new TCPSocket("127.0.0.1", 6789);
// Send data to server
mySocket.writeable.write("Hello World").then(
() => {
// Data sent sucessfully, wait for response
console.log("Data has been sent to server");
mySocket.readable.getReader().read().then(
({ value, done }) => {
if (!done) {
// Response received, log it:
console.log("Data received from server:" + value);
}
// Close the TCP connection
mySocket.close();
}
);
},
e => console.error("Sending error: ", e)
);
}
);
More details are outlined in the w3.org tcp-udp-sockets documentation.
http://raw-sockets.sysapps.org/#interface-tcpsocket
https://www.w3.org/TR/tcp-udp-sockets/
Another alternative is to use Chrome Sockets
Creating connections
chrome.sockets.tcp.create({}, function(createInfo) {
chrome.sockets.tcp.connect(createInfo.socketId,
IP, PORT, onConnectedCallback);
});
Sending data
chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);
Receiving data
chrome.sockets.tcp.onReceive.addListener(function(info) {
if (info.socketId != socketId)
return;
// info.data is an arrayBuffer.
});
You can use also attempt to use HTML5 Web Sockets (Although this is not direct TCP communication):
var connection = new WebSocket('ws://IPAddress:Port');
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
http://www.html5rocks.com/en/tutorials/websockets/basics/
Your server must also be listening with a WebSocket server such as pywebsocket, alternatively you can write your own as outlined at Mozilla
ws2s project is aimed at bring socket to browser-side js. It is a websocket server which transform websocket to socket.
ws2s schematic diagram
code sample:
var socket = new WS2S("wss://ws2s.feling.io/").newSocket()
socket.onReady = () => {
socket.connect("feling.io", 80)
socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}
socket.onRecv = (data) => {
console.log('onRecv', data)
}
See jsocket. Haven't used it myself. Been more than 3 years since last update (as of 26/6/2014).
* Uses flash :(
From the documentation:
<script type='text/javascript'>
// Host we are connecting to
var host = 'localhost';
// Port we are connecting on
var port = 3000;
var socket = new jSocket();
// When the socket is added the to document
socket.onReady = function(){
socket.connect(host, port);
}
// Connection attempt finished
socket.onConnect = function(success, msg){
if(success){
// Send something to the socket
socket.write('Hello world');
}else{
alert('Connection to the server could not be estabilished: ' + msg);
}
}
socket.onData = function(data){
alert('Received from socket: '+data);
}
// Setup our socket in the div with the id="socket"
socket.setup('mySocket');
</script>
In order to achieve what you want, you would have to write two applications (in either Java or Python, for example):
Bridge app that sits on the client's machine and can deal with both TCP/IP sockets and WebSockets. It will interact with the TCP/IP socket in question.
Server-side app (such as a JSP/Servlet WAR) that can talk WebSockets. It includes at least one HTML page (including server-side processing code if need be) to be accessed by a browser.
It should work like this
The Bridge will open a WS connection to the web app (because a server can't connect to a client).
The Web app will ask the client to identify itself
The bridge client sends some ID information to the server, which stores it in order to identify the bridge.
The browser-viewable page connects to the WS server using JS.
Repeat step 3, but for the JS-based page
The JS-based page sends a command to the server, including to which bridge it must go.
The server forwards the command to the bridge.
The bridge opens a TCP/IP socket and interacts with it (sends a message, gets a response).
The Bridge sends a response to the server through the WS
The WS forwards the response to the browser-viewable page
The JS processes the response and reacts accordingly
Repeat until either client disconnects/unloads
Note 1: The above steps are a vast simplification and do not include information about error handling and keepAlive requests, in the event that either client disconnects prematurely or the server needs to inform clients that it is shutting down/restarting.
Note 2: Depending on your needs, it might be possible to merge these components into one if the TCP/IP socket server in question (to which the bridge talks) is on the same machine as the server app.
The solution you are really looking for is web sockets. However, the chromium project has developed some new technologies that are direct TCP connections TCP chromium
I'm making a remote debugging tool for Unity(C#), and I've set up a C# WebSocket server in the game that emits Log messages.
The remote debugging client is in JavaScript, on a page served by an http server also created by the game.
I seem to be running into issues sending messages on some browsers, and I'm not sure why. I am running the websocket server on localhost and running the client locally, and I know that kind of stuff is not really liked by chrome/firefox. But the weird thing is that I'm not getting any hard errors or exceptions. Failures seem to fail silently.
I'm pretty certain that the issue is JS/Browser related as the C# websocket server works and receives connections in all cases.
Anyway, here's the socket part of the JS code:
var socket = null;
var host = "ws://"+window.location.hostname;
var port = 55000;
var url = host+":"+port+"/msg";
function CheckSocketStatus()
{
if(socket!=null){
console.log(socket.readyState);
}
}
function CreateSocket()
{
socket = new WebSocket(url);
socket.onopen = function()
{
// // Web Socket is connected, send data using send()
console.log("Socket Open!");
socket.send("Here's a client message for ya!");
};
socket.onmessage = function (evt)
{
var message = evt.data;
console.log("MSG: " + message);
var obj = JSON.parse(message);
console.log(obj)
console.log(obj.type)
if(obj.type == "log"){
console.log("Recieved Log");
handleLogMessage(obj);
}
};
socket.onerror = function()
{
console.log("Error!");
}
socket.onclose = function(event)
{
// websocket is closed.
console.log(event.code);
console.log("Connection is closed...");
socket = null;
};
}
In all cases, when I call CreateSocket() a socket gets created and successfully connects to the server. I also have that CheckSocketStatus() function which returns "1" after the socket opens (Which should mean open/ready to send/receive). After that, here are the results:
Chrome:
Chrome will immediately close after connecting. The only thing I do in the onopen() function is a console.log() and a send(). If I remove the send() then the socket will stay open. I do not receive any messages from the server.
Firefox:
Firefox will keep the socket open indefinitely even if I call the send() function in onopen(). However, the server does not receive any messages from the client and vice versa. I feel like I managed to it to send client->server earlier but I could not reproduce that while testing for this question.
Microsoft Edge:
Weirdly enough, Edge works just fine. I can receive and send messages. Works exactly as intended.
Node Webkit (nw.js):
I'm also trying to write this as a nw.js app. Predictably, as it's running on chromium (or something googly), it produces the same results as Chrome.
So I'm not really sure what's going on. I'm not really a web programmer so intricate http stuff is not really my forte. I'm really hoping it's just a Local file issue with chrome/firefox and that it'll work fine on those platforms if I'm connecting to an external host. I'll try to test this tomorrow at work with some non-localhost server, and I'll update with my findings.
I guess the answer I'm looking for is what these symptoms point to and how I can get chrome/firefox/webkit to work properly.
Also what does Edge do here that the others do not?
Thanks in advance! If you need any more info from me please just ask! I didn't want to overload this question just in case there's a simple answer.
Update:
So I just tried connecting from my laptop to my desktop and the same issues still persist. So to my surprise it's not a local issue. I'm a bit stumped. I might have to look at the server code as well. I've also been told to try to use a wrapper, like socket.io, that might solve some platform dependent issues.I've worked with Socket.io/Unity before but I don't think I was having these issues (I wasn't running a server on the C# side that time, there don't seem to be any good socket.io server implementations on C#, and I'm not sure if socket.io interfaces with normal websockets). So that might point to a problem with my implementation on the C# side.
So I figured it out, thanks to gman. I looked at some of his code and noticed that he used a setting in his WebSocketBehavior class called "Ignore Extensions".
The websocket-sharp documentation has this to say:
"If it's set to true, the service will not return the Sec-WebSocket-Extensions header in its handshake response."
"I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error."
So I guess that that header did not jive well with Chrome/Firefox. I'm still doing some testing but this solved the behavior I was seeing with those browsers.
So if you get similar errors, do that!
I have a vb.net application that opens a socket and listens on it.
I need to communicate via this socket to that application using a javascript running on a browser. That is i need to send some data on this socket so that the app which is listening on this socket can take that data, do some stuff using some remote calls and get some more data and put it back on the socket that my javascript needs to read and print it in the browser.
Ive tried, socket.io, websockify but none have proved to be useful.
Hence the question, is what i am trying even possible? Is there a way that a javascript running in a browser can connect to a tcp socket and send some data and listen on it for some more data response on the socket and print it to the browser.
If this is possible can some one point me in the right direction as to which would help me establish the goal.
As for your problem, currently you will have to depend on XHR or websockets for this.
Currently no popular browser has implemented any such raw sockets api for javascript that lets you create and access raw sockets, but a draft for the implementation of raw sockets api in JavaScript is under-way. Have a look at these links:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket
Chrome now has support for raw TCP and UDP sockets in its ‘experimental’ APIs. These features are only available for chrome apps and, although documented, are hidden for the moment. Having said that, some developers are already creating interesting projects using it, such as this IRC client.
To access this API, you’ll need to enable the experimental flag in your extension’s manifest. Using sockets is pretty straightforward, for example:
chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");
});
});
This will be possible via the navigator interface as shown below:
navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
() => {
// Permission was granted
// Create a new TCP client socket and connect to remote host
var mySocket = new TCPSocket("127.0.0.1", 6789);
// Send data to server
mySocket.writeable.write("Hello World").then(
() => {
// Data sent sucessfully, wait for response
console.log("Data has been sent to server");
mySocket.readable.getReader().read().then(
({ value, done }) => {
if (!done) {
// Response received, log it:
console.log("Data received from server:" + value);
}
// Close the TCP connection
mySocket.close();
}
);
},
e => console.error("Sending error: ", e)
);
}
);
More details are outlined in the w3.org tcp-udp-sockets documentation.
http://raw-sockets.sysapps.org/#interface-tcpsocket
https://www.w3.org/TR/tcp-udp-sockets/
Another alternative is to use Chrome Sockets
Creating connections
chrome.sockets.tcp.create({}, function(createInfo) {
chrome.sockets.tcp.connect(createInfo.socketId,
IP, PORT, onConnectedCallback);
});
Sending data
chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);
Receiving data
chrome.sockets.tcp.onReceive.addListener(function(info) {
if (info.socketId != socketId)
return;
// info.data is an arrayBuffer.
});
You can use also attempt to use HTML5 Web Sockets (Although this is not direct TCP communication):
var connection = new WebSocket('ws://IPAddress:Port');
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
http://www.html5rocks.com/en/tutorials/websockets/basics/
Your server must also be listening with a WebSocket server such as pywebsocket, alternatively you can write your own as outlined at Mozilla
ws2s project is aimed at bring socket to browser-side js. It is a websocket server which transform websocket to socket.
ws2s schematic diagram
code sample:
var socket = new WS2S("wss://ws2s.feling.io/").newSocket()
socket.onReady = () => {
socket.connect("feling.io", 80)
socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}
socket.onRecv = (data) => {
console.log('onRecv', data)
}
See jsocket. Haven't used it myself. Been more than 3 years since last update (as of 26/6/2014).
* Uses flash :(
From the documentation:
<script type='text/javascript'>
// Host we are connecting to
var host = 'localhost';
// Port we are connecting on
var port = 3000;
var socket = new jSocket();
// When the socket is added the to document
socket.onReady = function(){
socket.connect(host, port);
}
// Connection attempt finished
socket.onConnect = function(success, msg){
if(success){
// Send something to the socket
socket.write('Hello world');
}else{
alert('Connection to the server could not be estabilished: ' + msg);
}
}
socket.onData = function(data){
alert('Received from socket: '+data);
}
// Setup our socket in the div with the id="socket"
socket.setup('mySocket');
</script>
In order to achieve what you want, you would have to write two applications (in either Java or Python, for example):
Bridge app that sits on the client's machine and can deal with both TCP/IP sockets and WebSockets. It will interact with the TCP/IP socket in question.
Server-side app (such as a JSP/Servlet WAR) that can talk WebSockets. It includes at least one HTML page (including server-side processing code if need be) to be accessed by a browser.
It should work like this
The Bridge will open a WS connection to the web app (because a server can't connect to a client).
The Web app will ask the client to identify itself
The bridge client sends some ID information to the server, which stores it in order to identify the bridge.
The browser-viewable page connects to the WS server using JS.
Repeat step 3, but for the JS-based page
The JS-based page sends a command to the server, including to which bridge it must go.
The server forwards the command to the bridge.
The bridge opens a TCP/IP socket and interacts with it (sends a message, gets a response).
The Bridge sends a response to the server through the WS
The WS forwards the response to the browser-viewable page
The JS processes the response and reacts accordingly
Repeat until either client disconnects/unloads
Note 1: The above steps are a vast simplification and do not include information about error handling and keepAlive requests, in the event that either client disconnects prematurely or the server needs to inform clients that it is shutting down/restarting.
Note 2: Depending on your needs, it might be possible to merge these components into one if the TCP/IP socket server in question (to which the bridge talks) is on the same machine as the server app.
The solution you are really looking for is web sockets. However, the chromium project has developed some new technologies that are direct TCP connections TCP chromium