I'm creating node js application as a http server that communicate to tcp socket server, and the code look's like this:
var http = require('http');
var net = require('net');
var url = require('url') ;
const PORT=8080;
var client = new net.Socket();
client.connect(9000,'xxx.xxx.xxx.xxx', function(){
console.log('Connected');
});
function handleRequest(request, response){
var qo = url.parse(request.url,true).query;
if(typeof qo.q=="undefined"){
response.end("ERROR");
}else{
client.write(decodeURIComponent(qo.q));
client.on('data',function(data){
response.writeHead(200, {'Content-Type': 'text/html','Access-Control-Allow-Headers':'Content-Type,Access-Control-Allow-Headers,Access-Control-Allow-Origin,X-Powered-ByX-Powered-By','Access-Control-Allow-Origin': '*','X-Powered-By':'Poltak ganteng'});
response.end(data);
});
}
}
var server = http.createServer(handleRequest);
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
i'm afraid that code not working properly to handle multiple request at a time. is there any way to handle multiple request and get correct response to requestor?
You want to use req/res with your socket connection, you want to send uid at each client.write end your other service responde with the same uid for conserve the relation one to one to req/res, you don't have other choice for guaranteed unicities.
The have an expensive resource as TCP client (or clients) that has to be shared among node requests, so socket-pool can help you on that.
Related
I am trying to impliment websocket chat in mvc5 application using node.js and websocket for this I am using URL rewriter.
I am created a node server with following code.
var app = require('express')();
//creating http server
var server = require('http').createServer(app);
//add webrtc.io functionality to http server
var webRTC = require('webrtc.io').listen(server);
//port which is allocated dynamically by visual studeo IIS/iisexpress server, which of string formate.
var port = process.env.PORT;
//let the server in listen mode for the port id assigned by IIS server.
server.listen(port);
//this is for testing purpose, which returns the string, for the specified url request
app.get('/test/websocketcon', function (req, res)
{
res.end("working");
});
If i am trying to to access the https://localhost:44300/test/websocketcon. I am getting response as "working". But If I am trying to create new websocket I am getting error as
WebSocket connection to 'wss://localhost:44300/Home/websocketcon'
failed: Error during WebSocket handshake: Unexpected response code:
404
Code I have tried to create new websocket
var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
var address = protocol + window.location.host + window.location.pathname + "/websocketcon";
var createdwebsocket = new WebSocket(address );
your express route/server listens on for http requests, not wss. check this out: https://www.npmjs.com/package/express-ws
To explain in depth:
With the following lines of code, you have created a http server:
var app = require('express')();
var server = require('http').createServer(app);
http is what protocol you use when when you connect to http://yoursite.com. However, you are trying to connect a websocket to your server. to do this, you need to add a websocket listener and route to your server. This is because websockets don't work over the http protocol, they work over the websocket protocol.
To make a websocket server, checkout the link/module I have provided above. You should have a server which listens for both http requests and websocket requests. To make your current code work with websockets, what you need to do is make the following changes:
var app = require('express')();
var server = require('http').createServer(app);
// now add the express websocket functionality
var expressWs = require('express-ws')(app);
.
.
.
app.ws('/test/websocketcon', function (ws, req)
{
ws.send("Working!");
ws.on('message', function(msg) {
ws.send(msg);
});
});
I have websocket running on a node/Express server.
I need to send json string back and fourth between a websocket and a client.
However, if a user opens more than one browser's tab, I like for the websocket server to know that this is the same user that is already connected.
Here is the logic execution order
A user connects to the WebSocket.
The user sends json string to the WebSocket.
The WebSocket does things to the received message.
WebSocket finally sends the new message to all the tabs that a user have open.
The new message should be returned only to that user not others.
How can I establish one connection between a user and the WebSocket?
This is my server setup
var env = require('./config');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var clients = [];
server.listen(env.socket.port, env.socket.host, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Websocket running at http://%s:%s', host, port);
});
app.get('/', function (req, res) {
res.send('Welcome!');
});
io.on('connection', function (socket) {
clients[] = socket;
socket.emit('chat', { hello: 'world' });
socket.on('chat', function(msg){
console.log('message: ' + msg);
sendAll(msg);
});
});
function sendAll (message) {
for (var i=0; i< clients.length; i++) {
clients[i].send("Message For All: " + message);
}
}
If you do not have authentication for the users, then you need some browser-specific piece of data to correlate users on your backend.
I don't know about cookies (haven't used them), but one way at the JavaScript level would be to store a locally generated random ID (of sufficient length so that you don't have to worry about collisions) in local storage in the browser, and transmit this as part of the initial message at the WebSocket level.
I am having an issue sending over an array of information from my client.js to the node server using an http POST request. After a couple of days I think I have narrowed it down.
My current set up is the following:
Server
After X amount of time, the server will start to ask clients to send their collected data.
The server sends out only one request at a time, waiting to receive that clients info before sending a request to the next client
Client
The client receives the request from the server
Http stuff to send POST request is set up
Array data is converted to json
1000ms is waited before sending the http post request
Server
Post request is received & that data is added to a local array
My server.js
var http = require('http')
, connect = require('connect')
, io = require('socket.io')
, fs = require('fs')
, uuid = require('node-uuid')
, _ = require('lodash');
// omitted event handers & pubnub setup
var app = connect().use(connect.static(__dirname)).use(connect.directory(__dirname));
var server = http.createServer(app);
server.listen(8888);
io = io.listen(server);
// Following handles sending request to clients
function phaseTwo() {
var count = 0;
setTimeout(function() {
pubnub.publish({
channel: 'channel' + viewers[count],
message: { message: 'measurements',
uuid: 'Server',
receiver: viewers[count] }
});
// set up server to listen for http POST
app.use(function(req, res) {
if (req.method == 'POST') {
count++;
req.on('data', function(chunk) {
// add that array into one main array
latencyData.push.apply(latencyData, chunk);
dataCollected++;
});
pubnub.publish({
channel: 'channel' + viewers[count],
message: { message: 'measurements',
uuid: 'Server',
receiver: viewers[count] }
});
}
}); // end app.use
}, msDuration);
}
client
if (message.message == 'measurements') {
console.log(' Received measurements event');
var http = new XMLHttpRequest();
var url = 'http://localhost:8888/';
http.open('POST', url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// http.setRequestHeader("Content-length", latency.length);
// http.setRequestHeader("Connection", "close");
var myJsonString = JSON.stringify(latency);
setTimeout( function() {
http.send(myJsonString);
}, 1000);
}
The problem is that without that 1000ms delay on the client side, the server does not receive all the client's data. Even worse, when trying to scale up a few hundred clients, no more http posts are sent to the server after 240 clients have sent their info (there is enough ram for them)
With no delay on the client making the POST request, the server should be waiting for the current client to send over their information over before continuing. The other issue is that even with under the 240 clients, say testing 200 clients, even with no delay only about 10% of their data is received (this stuff is written to a text file at the end)
Im very new to using http post/get stuff so I think that is the issue.
Is there anything immediately wrong from anyone experiences with http or nodejs stuff?
edit: I found one mistake. Back on the server side, on the post request whatever data is gotten from the server is added right away to the local array on the server without first making sure it's an array. Im not completely sure if this would break things enough to be the source of my problem
A POST can be pretty simply handled with Express.
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(bodyParser());
app.post('/', function(req, res) {
console.log(req.body);
res.send('data retrieved');
});
app.listen(3000);
Make proper route in server to handle incoming requests make your app aware of such routes.
You can console.log(req) to check it in server side how you are getting the request with all the data.
I am trying to make a console based node.js application which simulates 1000/+ clients Connections to an existing node.js based TCP server app.
Update: With the current version of this code^ I am getting an error TypeError: cannot call method 'write' of undefined at: connx[connNos].Write(str). I guess I will have to rethink/rewrite this piece of code; any pointers are welcome.
Till now this is what I came up with but this doesn't work as implied:
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 7000;
var timeout = 30000;
var connx = [];
for(var connNos = 0; connNos < 10; connNos++){
connx[connNos] = net.createConnection(PORT,HOST);
//connx.push(connx[connNos]);
connx[connNos].on('connect', function(err){
console.log('Client: Connected');
});
connx[connNos].on('error', function(data){
console.log('>> ' + data);
});
connx[connNos].on('close', function(){
console.log('Client: Conn Closed');
process.exit();
});
process.stdin.on('data', function(data){
console.log('sending data..');
//connection.write(data);
var str = "486229^4049^1018436^D^2013-04-01 00:02:09^22.715939100^88.374148220^27238^0^308^0^192.168.1.1^1^2013-04-01 19:49:04";
connx[connNos].write(str);
//connection.end();
});
process.stdin.resume();
}
Any help will be appreciated
TIA :D
From the doc
net.createConnection(options, [connectionListener])#
Constructs a new socket object and opens the socket to the given location. When the socket is established, the 'connect' event will be emitted.
For TCP sockets, options argument should be an object which specifies:
port: Port the client should connect to (Required).
host: Host the client should connect to. Defaults to 'localhost'.
localAddress: Local interface to bind to for network connections.
For UNIX domain sockets, options argument should be an object which specifies:
path: Path the client should connect to (Required).
I guess
connx[connNos] = net.createConnection(PORT,HOST);
should be
connx[connNos] = net.createConnection({port:PORT,host: HOST});
Think async, most probably reason is that when you call socket.write socket connection was not estanblished. You should check connection before call or you can put code in connection listener.
I'm relatively new to node.js and it's addons, so this is probably a beginnersquestion.
I'm trying to get a simple HTML page on a webserver connect to a different server running node.js with websocket.io.
My code looks like this:
Client
<script src="socket.io/socket.io.js"></script>
<script>
// Create SocketIO instance, connect
var socket = new io.Socket();
socket.connect('http://127.0.0.1:8080');
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
// Add a connect listener
socket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
console.log('The client has disconnected!');
});
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
};
</script>
Serverside
// Require HTTP module (to start server) and Socket.IO
var http = require('http');
var io = require('socket.io');
var port = 8080;
// Start the server at port 8080
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(200,{ 'Content-Type': 'text/html' });
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(port);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function(client){
console.log('Connection to client established');
// Success! Now listen to messages to be received
client.on('message',function(event){
console.log('Received message from client!',event);
});
client.on('disconnect',function(){
clearInterval(interval);
console.log('Server has disconnected');
});
});
console.log('Server running at http://127.0.0.1:' + port + '/');
Starting up the server works fine and running http://localhost:8080 in my browser also works, returning 'Hello Socket Lover' as expected. But I want to make a different page talk to the sockets, not run one from node.js.
But when I run it, nothing happens and the Chrome console returns:
Failed to load resource http://undefined/socket.io/1/?t=1333119551736
Failed to load resource http://undefined/socket.io/1/?t=1333119551735
I've been at this all day. Any help?
Have you tried loading the socket.io script not from a relative URL?
You're using:
<script src="socket.io/socket.io.js"></script>
And:
socket.connect('http://127.0.0.1:8080');
You should try:
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
And:
socket.connect('http://localhost:8080');
Switch localhost:8080 with whatever fits your current setup.
Also, depending on your setup, you may have some issues communicating to the server when loading the client page from a different domain (same-origin policy). This can be overcome in different ways (outside of the scope of this answer, google/SO it).
You need to make sure that you add forward slash before your link to socket.io:
<script src="/socket.io/socket.io.js"></script>
Then in the view/controller just do:
var socket = io.connect()
That should solve your problem.
Instead of:
var socket = new io.Socket();
Try:
const socket = io();
Also add a server file:
const http = require('http');
const express = require('express');
const app = express();
const server = http.createServer(app);
app.use(express.static(__dirname + '/public'));
const io = require('socket.io')(server);
const PORT = 5000;
server.listen(PORT, () => {
console.log(`Server is Listening On Port ${PORT}`);
});