Node.js and web-socket-js simple client server not opening - javascript

My server.js seems to be correct..
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, "mysite.com");
console.log('Server running at mysite.com:1337/');
The meat of my client is below.
function init() {
// Connect to Web Socket.
// Change host/port here to your own Web Socket server.
ws = new WebSocket("ws://mysite.com:1337");
// Set event handlers.
ws.onopen = function() {
output("onopen");
};
}
If I go to http://www.mysite.com:1337 I correctly receive Hello World! However, when I try to connect using my client, and debug in Fire bug, I get the following output.
[WebSocket] connected
[WebSocket] request header: GET / HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Host: mysite.com:1337 Origin: http://www.mysite.com Cookie: Sec-WebSocket-Key1: 115 17 p^!x-93 IERc16 7 Sec-WebSocket-Key2: 1 75 7Z i `. 8u $l031 4j9
[WebSocket] sent key3: ±Ôñ<g
[WebSocket] closed
And the WebSocket is automatically closed before I have any chance to do anything. Can anyone please shed some light on the error I am receiving and what do you think I should do?

You have created a node.js HTTP server but you are trying to connect to it as a WebSockets server. The WebSockets protocol is not plain sockets and it is not plain HTTP request. WebSockets have an HTTP like handshake but after that you have a full-duplex connection (like sockets and unlike HTTP) that has a small amount of message framing (unlike plain sockets).
Try using Socket.IO or node-websocket-server if you want to create a node.js WebSockets server. On the other hand if you are wanting to connect from Javascript to a regular HTTP server then use one of the great Javascript libraries with AJAX support such as jQuery.

Related

Socket.IO attempting to connect through https:// instead of wss:// and getting a CORS error

I'm switching from JavaScript's vanilla WebSocket API to Socket.IO for real-time data about cryptocurrency prices. While using the regular WebSocket I had no problem connecting to Kraken and getting the data I need. However, when trying to connect with Socket.IO, I get a CORS error.
Access to XMLHttpRequest at 'https://ws.kraken.com/socket.io/?EIO=3&transport=polling&t=Mxg8_5_' from origin has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
In in the Chrome dev tools network tab, I'm getting an Invalid request response from Kraken. I assume Socket.IO is trying to send some sort of preflight request when trying to establish a websocket connection and failing due to Kraken's CORS policy for http requests. Is there a way to completely bypass this XMLHttpRequest attempt and immediately try a websocket connection, seeing as the regular WebSocket API has no issues establishing this connection and doesn't seem to send a preflight request? Here are both the vanilla and the Socket.IO sockets:
// vanilla websocket
const vanillaWS = new WebSocket('wss://ws.kraken.com');
vanillaWS.onopen = () => {
console.log('vanilla websocket opened');
}
vanillaWS.onmessage = (message) => {
console.log(message.data);
}
// socket.io websocket
const ioSocket = io('wss://ws.kraken.com');
ioSocket.on('connect', () => {
console.log('socket.io socket opened');
});
ioSocket.on('message', (message) => {
console.log(message.data);
});
As you can see, these should be functionally very similar, but while the first one works as expected, the second one is throwing the error.
From the documentation:
What Socket.IO is not
Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed
uses WebSocket as a transport when possible, it adds some metadata to
each packet: the packet type, the namespace and the packet id when a
message acknowledgement is needed. That is why a WebSocket client will
not be able to successfully connect to a Socket.IO server, and a
Socket.IO client will not be able to connect to a WebSocket server
either. Please see the protocol specification
here.
So if the endpoint you're trying to use isn't running a Socket.IO server, this isn't going to work.
That said, if it is, you can force the use of websockets using the transports parameter:
const ioSocket = io(endpoint, {
transports: ['websocket'] // forces websockets only
});
Bottom Line: Socket.IO is not a replacement for a WebSockets connection. Socket.IO uses WebSockets to accomplish its goal: "Socket.IO is a library that enables real-time, bidirectional and event-based communication between the browser and the server".
You're getting the CORS error because socket.io attempts pure HTTP-based long-polling connection first and that's what fails. You should manually set your client to attempt websocket first:
var options = {
allowUpgrades: true,
transports: ['websocket', 'polling'],
};
var sock = io(server, options);
sock.on('connect', () => {
console.log('socket.io socket opened');
});
sock.on('message', (message) => {
console.log(message.data);
});
From the socket.io docs:
With websocket transport only
By default, a long-polling connection is established first, then
upgraded to “better” transports (like WebSocket). If you like to live
dangerously, this part can be skipped:
const socket = io({ transports: ['websocket'] });
// on reconnection, reset the transports option, as the Websocket //
connection may have failed (caused by proxy, firewall, browser, ...)
socket.on('reconnect_attempt', () => { socket.io.opts.transports =
['polling', 'websocket']; });

Rest API based TCP client using Node js

I have tried to create TCP Client with rest api using nodejs and also used net module to establish tcp connection to send/receive data. The main idea is to use this restAPI from browser to load test TCP Connections.
Here in my case there are 2 steps involved while load testing TCP.
1) send initial TCP request which has token for authentication.
2) then send other TCP request to send some data.
The issue is when i try to send 2nd TCP request after authentication. Getting response as invalid session.
Please suggest if i can send TCP request for authentication and using same session/connection while making subsequent requests.
I am new to node js. My Apologize if I have not provided enough details or done some thing invalid.
Initially I have used Packet Sender application and enabled persistent TCP Connection option in it. It worked well as expected but this is for single user and cant use this tool for load testing. Here in this tool with persistent TCP enabled I can see the local port is fixed and not changing upon sending multiple requests but with my node js code i can see the local port is getting changed upon every new request.
I have also used TCP Sampler in Jmeter with reuse Connection option but not working when i send 2nd request after authentication.
var Net = require('net');
var express = require("express");
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.post('/api/push', function (req, res) {
var reqBody = req.body.reqBody;
var req = JSON.stringify(reqBody);
const client = new Net.Socket({
allowHalfOpen: true
});
client.connect({
port: req.body.port,
host: req.body.host
}, function () {
client.write(req);
});
client.on('data', function (chunk) {
res.write(chunk.toString());
//Tried to use client connection information, but didnt worked not sure if i missed something.
console.log(JSON.stringify(client));
// Tried commenting below client.end but no luck.
client.end();
});
client.on('end', function () {
res.end();
});
client.on('error', function (err) {
console.log("Error: " + err.message);
res.write(err.message);
client.end();
});
});
app.listen(1234, () => {
console.log("Server running on port 1234");
});
1) send restAPI with TCP server host/port and request body for authentication.
2) send another restAPI to use same TCP connection and send data. but it failed for mere
Inspect the behavior and get the cookies details and preserve the same in HTTP cookie manager to reuse the same session for the second request. Just adding http cookie manager also might work. Please check,

No need to set up a local server with Node.js?

I see when I want write a Node.js web application on my local machine, I don't need to set-up a local server using WAMP or MAMP. What is node.js really doing behind the scenes? I am providing this code to make a simple hello world web app:
var http = require("http");
http.createServer(function(request,response){
response.writeHead(200, {"content-type":"text/html"});
response.write("hello world");
response.end();
}).listen(8080);
console.log("server is running....");
When loading in my browser URL bar "localhost:8080" it works.
How this is working as and why don't I need a local server when working with Node.js?
You do have a local server... it's your Node.js application.
When you call http.createServer(), it creates an HTTP server. When you call .listen() on that server, it binds to the requested port, and optionally requested address, and listens for connections. When data comes in on those connections, it responds like any other HTTP server.
The HTTP server uses your request/response callback, firing it whenever a valid HTTP request comes in.
Because node comes out of the box with all the libraries you need to run a webserver, the http library that you are using is opening the 8080 port and handling the request with the function you provided
This part:
function(request,response){
response.writeHead(200, {"content-type":"text/html"});
response.write("hello world");
response.end();
}
No, you don't need it. Because node itself can be your webserver, just like in your example. Node is built on V8, which is chrome JavaScript engine .
Take a look a Express js module that gives you lots of features out of the box

How to create a node.js server?

I'm trying to create my first node.js server and I have some problems.
When I use
var http = require("http");
var server = http.createServer();
server.listen(8888);
No connection can be established to the server.
But when I use this
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
The server lands ok.
I used this in a file called server.js and runned the command node server.js. I'm using v 0.12.0
What am I missing? Why the server doesn't work on the first case?
The first block of code creates a server and listens on a port.
When you point a browser at it, the browser makes a request and then waits for a response.
You haven't told the server what to respond with, so it sits there doing nothing.
Eventually the browser times out.
In the second set of code, you've told the server how to respond to requests.

HTML code from node js not interpreted as such by the browser

I have created my first node js application: a simple webserver.
Here's the code:
// Load the http module to create an http server.
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("ARD Tagesschau\n");
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
When I connect to the server via my browser I get the full string specified in my code as a web page.
Shouldn't the browser interpret that HTML code and display a link? Why do I get the full HTML code shown as plain text?
You have explicitly said that you are returning plain text, not HTML. The browser therefore treats it as plain text.
If you want HTML to be treated as HTML then say it is HTML:
{"Content-Type": "text/html"}
(Although you should send back an HTML document and not a fragment of HTML).
Following Code works for me:
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.end("ARD Tagesschau\n");
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
You need to set the Headers. For more information check in Node API docs here.
Check the difference in your firebug or dev tools to understand how browser interprets differently based on Header Content-Type.

Categories

Resources