Ws: Cannot connect WS client to WS server

Created on 21 Jul 2016  Â·  8Comments  Â·  Source: websockets/ws

I can connect a default WebSocket client to WS server without problems but is unable to connect WS client to WS server.
WS version is 1.1.1
Server side is Node.js

This configuration works well
The default WebSocket client:

ws = new WebSocket('ws://localhost:40510');
ws.onopen = function (evt) {
   ws.send(“Hello!”);
};

The WS server:

var WebSocketServer = require("ws").Server;
var wss = new WebSocketServer({ port: env.PORT });
wss.on("connection", function (ws) {
   console.info("websocket connection open");
});

This configurations doesn't work
WS client:

var WebSocket = require("ws");
ws = new WebSocket('ws://localhost:40510');
ws.onopen = function (evt) {
   ws.send(“Hello!”);
};

The websocket status changes to WebSocket.CONNECTING, and fails with an error:

TypeError: Failed to fetch at TypeError (native)

Adding HTTP server to WS doesn't help:

var http = require('http');
var WebSocketServer = require("ws").Server;
var httpServer = http.createServer(function (req, res) {
   res.setHeader('Access-Control-Allow-Headers', req.headers.origin);
});
httpServer.listen(env.PORT, function () {    
    console.log('Server is listening at port: ' + env.PORT);
});
var wss = new WebSocketServer({ server: httpServer });
wss.on("connection", function (ws) {
   console.info("websocket connection open");
});

I have console message that the http server is listening and receive the same error:

TypeError: Failed to fetch at TypeError (native)

This solution doesn’t work too (Server side):

var wss = new WebSocketServer({ port: env.PORT, headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Headers": "http://localhost:3000",
        "Access-Control-Allow-Methods": "PUT, GET, POST, DELETE, OPTIONS"
} });

Without “Access-Control-Allow-Headers” I receive this error:

In this case I receive an error right away:
Fetch API cannot load http://localhost:40510/.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
The response had HTTP status code 426.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Most helpful comment

Working fine for me.

// server.js

"use strict";

const WebSocketServer = require("ws").Server;
const wss = new WebSocketServer({ port: 2222 });

wss.on("connection", (ws) => {
   console.info("websocket connection open");

   if (ws.readyState === ws.OPEN) {
       ws.send(JSON.stringify({
           msg1: 'yo, im msg 1'
       }))

       setTimeout(() => {
            ws.send(JSON.stringify({
                msg2: 'yo, im a delayed msg 2'
            }))
       }, 1000)
   }
});
// client.js

"use strict";

const WebSocket = require('ws');

let ws = new WebSocket('ws://localhost:2222');

ws.onopen = function() {
    console.log('open')
}

ws.onmessage = function(ev) {
    let _data = JSON.parse(ev.data);

    console.log(_data);
}
// client.go

package main

import (
    "fmt"
    "golang.org/x/net/websocket"
)

func main() {
    ws, err := websocket.Dial("ws://localhost:2222", "", "http://localhost:2222")

    if err != nil {
        fmt.Println(err)
        return
    }

    for {
        var m string

        websocket.Message.Receive(ws, &m)

        fmt.Println(m)
    }
}

All 8 comments

The connection works only when WS client is also running by Node.js
I want to run it from the browser as a part of the index.html

P.S. is there npm package for client-side WS like https://github.com/socketio/socket.io-client where all files from lib are combined in one JS file?

same problem here, WS only works if I run it on Electron.
But after I package it with webpack and host will express, it just don't work with browser (Chrome v52.xxx)

When I dig into that, I found the request is sent with http:// insteads of ws:// is that normal?

May be any modules missing? any ideas?

Working fine for me.

// server.js

"use strict";

const WebSocketServer = require("ws").Server;
const wss = new WebSocketServer({ port: 2222 });

wss.on("connection", (ws) => {
   console.info("websocket connection open");

   if (ws.readyState === ws.OPEN) {
       ws.send(JSON.stringify({
           msg1: 'yo, im msg 1'
       }))

       setTimeout(() => {
            ws.send(JSON.stringify({
                msg2: 'yo, im a delayed msg 2'
            }))
       }, 1000)
   }
});
// client.js

"use strict";

const WebSocket = require('ws');

let ws = new WebSocket('ws://localhost:2222');

ws.onopen = function() {
    console.log('open')
}

ws.onmessage = function(ev) {
    let _data = JSON.parse(ev.data);

    console.log(_data);
}
// client.go

package main

import (
    "fmt"
    "golang.org/x/net/websocket"
)

func main() {
    ws, err := websocket.Dial("ws://localhost:2222", "", "http://localhost:2222")

    if err != nil {
        fmt.Println(err)
        return
    }

    for {
        var m string

        websocket.Message.Receive(ws, &m)

        fmt.Println(m)
    }
}

The browser at its lowest level can use only one API for websockets, the "WebSocket" and it still doesn't support sending custom headers, opposite to websocket client run by to Node.js.
So, this issue is not relevant.

Kind of unrelated to this question but did not want to open a separate issue, when using requests library, there is an option called json which if you set to true, the body from (error, response, body) arrives in JSON form readily but I see that in all the snippets posted when you call ws.onmessage , you have to manually do JSON.parse, isnt there a way to get the message as JSON objects readily instead of strings?

@slidenerd In my opinion, since ws is supposed to be a small core lib, it's not meant to have this kind of abstractions, so it's up to the userland to stringify and parse jsons as they come and go. Not sure if there are other reasonings behind it, though.

thanks for the clarifying the goals of the lib, from an abstraction perspective, what you say makes sense 👍

https://github.com/websockets/ws/issues/790#issuecomment-242308095
@lamaslam I have the same problem. "request is sent with http:// insteads of ws://"
Using browser it always goes to http.
Did you get an answer to that?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pacmac picture pacmac  Â·  3Comments

makc picture makc  Â·  4Comments

nabeelio picture nabeelio  Â·  5Comments

quesurifn picture quesurifn  Â·  3Comments

ImBundle picture ImBundle  Â·  3Comments