so i am connecting a client to a server using websockets (ws). i successfully send msgs to the server and send it back to the client.Problem is when I try to write the received message to a file the server disconnects the client. The message is successfully written but i end up disconnecting client. Looks like something about the write functions disconnect my client. I am using fs.writFile(), I already tried fs.createWriteStream(). Reading the file however does not disconnect it.
const http = require('http');
const WebSocket = require('ws')
const fs = require('fs');
let counts = [0,0]
const server = http.createServer((req,res)=>{
console.log(' Received request for ' + request.url);
});
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection',(ws)=>{
console.log("serving...")
ws.on('message',(message)=>{
console.log("Received:"+message)
if(message ==='1'){
counts[0]=parseInt(counts[0])+1
fs.writeFile('votecnts.txt',`${counts[0].toString()} ${counts[1].toString()}`,(err) =>{
if(err) throw err
})
}
else if (message==='2'){
counts[1]=parseInt(counts[1])+1
fs.writeFile('votecnts.txt',`${counts[0].toString()} ${counts[1].toString()}`,(err) =>{
if(err) throw err
})
}
else{console.log(typeof(message))}
ws.send("cand_one: "+counts[0].toString()+"\n cand_two: "+counts[1].toString())
})
ws.on('close',function(){
console.log("lost client")
})
})
So I figured it out. I was running both server and client on localhost while developing. And therefore the file directories are the same. I later found out that it is impossible to write to file in javascript at the client side because of security reasons. So all I did was to change the url of the server to a remote machine and I was able to write to file using server code. specifically with the writeFile() function in the code above. I actually did not have to touch my code. It was just about configuration and set up.
Related
I'm definitely a newbie with JS and node. I have telescope management software called SkyX Pro, and it has the ability to run a TCP Server on port 3040. I can connect to it using Netcat and hand it a Javascript starting with //* Javascript *// this works and allows me to startup cameras and other equipment and send commands for taking pictures etc. The issue is it needs to be run from a batch file which makes getting any information back to an HTML page tough (Like Camera, focuser and filter wheel status and temperatures).
The NC call looks like "NC localhost 3040 < Javascript-file.js
To get around the browser to local machine security issues I want to run this from node.js with maybe socket.io-client if possible, but I don't know the proper syntax for it.
I have seen plenty of client syntax sending hello's etc. but nothing send javascript and allowing for two-way connectivity that I can understand.
I have tried using:
var socket = io.connect('http://localhost');`enter code here`
socket.on('httpServer', function (data) {
console.log(data);
document.write(data + "\r\n");
socket.emit('tcp', "For TCP");
});
const net = require('net');
const client = new net.Socket();
client.connect({ port: 3040, host: process.argv[2] });
client.on('data', (data) => {
console.log(data.toString('utf-8'));
But I do not understand it well enough to troubleshoot why it's not working.
Any help would be wonderful, and please treat me like a baby that needs its step by step.
Cheer
Peter
Reading [1], We can assume socket-io isn't the perfect fit for you, because that Server you have sound like a typical tcp-socket server, not a socket.io server ( which requires special headers ) or a web-socket server.
So you only needs "net" library to do the job.
const net = require('net');
// module to send a message to TCP-socket server and wait for the response from socket-server
const sendAndReceive = async (client, message) => {
client.write(message);
let response = null
await ( new Promise( (resolve, reject) => {
client.on('data', function(data) {
response = data;
resolve()
});
}))
return response;
}
// send a single message to the socket-server and print the response
const sendJSCode = (message) => {
// create socket-client
const client = new net.Socket();
client.connect(3040, 'localhost', async function() {
console.log('Connected');
// send message and receive response
const response = await sendAndReceive(client, message)
// parse and print repsonse string
const stringifiedResponse = Buffer.from(response).toString()
console.log('from server: ', stringifiedResponse)
// clean up connection
client.destroy()
});
}
sendJSCode('var Out; \n Out="TheSky Build=" + Application.build \n\r')
This script will:
Initiate a socket client
on connection successfully, client sends a message
client receives back response from that message
client prints response to terminal
Note that TheSkyX has a limitation of 4096 bytes for each message[2], any more than that and we will need to chunk the message. So you may want to keep the js-code short and precise.
that snippet I gave is minimal, it doesn't handle errors from server. If you want, you can add client.on("error", .. ) to handle it.
Your point of connecting to the socket server directly from browser is very intriguing, unfortunately it is not allowed by modern browsers natively due to security concerns 3
[1] https://socket.io/docs/#What-Socket-IO-is-not:~:text=That%20is%20why%20a%20WebSocket%20client,to%20a%20plain%20WebSocket%20server%20either.
[2] https://www.bisque.com/wp-content/scripttheskyx/scriptOverSocket.html#MSearchField:~:text=set%20to%204096%20bytes
I'm trying to create a websocket server that receives a message and then closes. From there, the script should behave as if the websocket server never existed...
I can't seem to figure why the websocket server keeps hanging.
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 8080 })
wss.on('connection', ws => {
ws.on('message', message => {
console.log(`Received message => ${message}`);
ws.send('Hello! Message From Server!!');
});
ws.on("close", ws => {
console.log("closed!");
ws.close();
//ws.terminate();
});
});
Both ws.close and ws.terminate leave the script hanging after the message is received. How do I truly close the server and let the script act is if the websocket server never existed? I want to process the information I received from the client.
This answer (https://stackoverflow.com/a/49791634/5527786) suggests how to close the server but it doesn't work. Not even process.exit stops it!
Edit: It looks like I was supposed to do wss.close(). How can I now process the message that I received from the websocket server? I'm assuming I need to return a promise that I resolve somewhere?
I have been working on a websocket client application.
I am currently using the ws client library, because it is easy to add some headers (I need this for authentication purposes). I have made a successful connection to the server, but now I need to connect to a specific channel.
Current code:
const WebSocket = require('ws');
var option = {
headers: {
api_key: 'xxxxx'
}
};
// I know this is not a correct url, but I removed it for security reasons
const url = '../websocket/';
const wss = new WebSocket(url, option);
wss.on('open', () => {
console.log("Connection is succesfull");
wss.on('message', message => {
console.log(message);
});
});
When I ran the code it prints the "Connection succesfull", but now I want to connect to a channel called /people. How can I do this.
I have tried several things like:
Changed the url websocket/people.
This doesn't work because it first needs to authenticate to user, before making a connection to a channel
Changed the url to websocket/?people.
I don't get an error, but I also don't get response back when something is send to this channel.
Add this in the open function:
wss.on('/people', message => {
console.log(message);
});
I don't get an error, but I also don't get response back when something is send to this channel.
For the record. I only have access to the documentation and not to the server.
I'm using socket.io-client to create a socket connection to my locally-running server. See my code below:
// Working example of connecting to a local server that is not SSL protected
var io = require('socket.io-client')
var socket = io.connect('http://localhost:3000', {reconnect: true});
socket.on('connect', function(){ console.log("inside 'connect'") } );
socket.on('connection', function(){ console.log("inside 'connection'") } );
socket.on('event', function(data){ console.log("inside 'event'") } );
socket.on('disconnect', function(){ console.log("inside 'disconnect'") } );
var payload = {email: 'fake#gmail.com', password: 'tester'};
var tokens = {browserId: 'b965e554-b4d2-5d53-fd69-b2ca5483537a'};
socket.emit("publish", {logic:"user", method:"signIn"}, payload, tokens, function(err, creds) {
console.log("inside the socket client emit callback. err: " + err);
console.log("creds: " + creds);
});
Now for my problem. As I stated in the comment at the top of that code, I can connect to my local nodejs server and get the response I expect when I turn off SSL encryption on my server. As soon as I turn SSL on, I stop getting any response at all from the code above. I don't see any message in my server logs or from the command line, where I'm running the code above with node.
My goal is to be able to run the code above, with SSL turned on in my server, and get the same response that I get when SSL is turned off. I've tried a bunch of variations on the code I included above, such as:
connecting to "https://localhost:3000"
connecting to "//localhost:3000"
connecting to "https://localhost:3443" (this is the port I have to connect to when I have the nodejs server running with SSL)
changing {reconnect:true} to {reconnect:true,secure:true}
I'm truly stumped, and I've been doing a bunch of research on the web and on my node server. It's my company's code and I didn't originally implement the SSL components, so I've spent a few hours looking at our code and trying to understand how adding SSL changes everything. I'm also a student and have about 2 years of experience behind me, so I'm good but I'm no expert. Have I said anything above that indicates if my task is impossible to achieve, or if maybe I have just overlooked something? Any leads on things to check out would be appreciated :)
I have a problem that i don't seems to be able to solve it. I'm doing some kind of integration with remote system and my code is in iframe but that can't be important for this one i hope :).
I'm trying to send a message from server to specific room/client to begin session. First thing I do is when user log in, I emit message from client side with username.
CLIENT.JS
conn.on('connect', function () {
conn.emit('session', { username: 'some_username' });
}, false);
And on server side i get message and join socket to the room.
SERVER.JS
socket.on('session', function(session) {
socket.join(session.username);
});
I have another module that communicates with this server.js script through redis. So i have two more events in server.js
SERVER.JS
var userCreate = redis.createClient();
userCreate.subscribe("userCreate", "userCreate");
var userDestroy = redis.createClient();
userDestroy.subscribe("userDestroy", "userDestroy");
userCreate.on("message", function(channel, data) {
socket.to(JSON.parse(data).username).emit('beginSession', data);
});
userDestroy.on("message", function(channel, data) {
socket.to(JSON.parse(data).username).emit('endSession', data);
socket.leave(JSON.parse(data).username);
});
But when ever i try to emit message from server to client i broadcast message to everyone. What am I doing wrong?
Well, from the syntax point of view you are doing everything correct.
Didn't you forget to specify the userId property in the endSession?
userDestroy.on("message", function(channel, data) {
socket.to(JSON.parse(data).userId).emit('endSession', data);
socket.leave(JSON.parse(data).userId);
});
If that doesn't work - you should provide the contents of a data object