i am new to websocket using pywebsocket, basically trying to create a simple chat application with websocket and pywebsocket.
Until now i am done with following script
if ("WebSocket" in window)
{
//alert("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://192.168.1.3:9998/echo");
ws.onopen = function()
{
// Web Socket is connected, send data using send()
console.log("Channel opened");
//ws.send("Message to send");
//alert("Message is sent...");
//console.log("Message is sent...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
//alert("Message is received..."+received_msg);
console.log("message : "+received_msg);
};
ws.onclose = function()
{
// websocket is closed.
//alert("Connection is closed...");
console.log("connection closed");
};
}
else
{
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
function sendmessage(){
msg=document.getElementById("chat").value;
console.log(msg);
ws.send(msg);
document.getElementById("chat").value="";
}
Now the problem is the messages that are sent are echoed to the system itself, if another client connect to same channel its messages are echoed to itself, they are sent to another client which is connected with same channel.
pywebsocket is initialized as follows
python standalone.py -p 9998 -w ../example/
So how can i connect two system and allow chat.
Thanks in advance
Not sure, but if you want to broadcast any received message (sent by any connected client) to all other currently connected clients, that is not "echo" .. but "broadcast".
Here is an example using AutobahnPython.
Disclosure: I am original author of Autobahn and work for Tavendo.
Related
Background: I have a node.js server running on my localhost (call this Server A); and an external server running node.js at https://example.net:3000 (call this Server B). I do not control or have access to Server B (it is a dashboard site for an IoT device in my home), but I need to connect to is using socket.io and emit a specific message.
I can connect to it easily from a flat javascript file (client-side), but need it running server side (ultimate goal is to make it into something I can call with an HTTP request); and examples such as How to connect two node.js servers with websockets? suggest I should be able to use socket.io-client from node.js with nearly the same code to achieve the same results. But when I run the code from node.js, I cannot connect to the socket.
Below is the code that works successfully in flat javascript file. I know it works because I see 'socket connect' in the console, and I can also test for the the socket emit at the end.
var myemail = "email#gmail.com";
var device_id = '12345';
// Create SocketIO instance, connect
var socket = io.connect('https://example.net:3000');
socket.on('connect', function(){
try {
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
} catch(e) {
console.log(e);
}
});
socket.emit("/" + device_id, "45678");
...and below is the code I cannot get to work when running from my node.js instance. I'd expect a message 'socket connect' in the command line log and get nothing.
var express=require('express');
var http=require('http');
var app=express();
var server = http.createServer(app);
//Variables
var myemail = "email#gmail.com";
var device_id = '12345';
var io = require('socket.io-client');
var socket = io.connect('https://example.net:3000');
//Connect listener
socket.on('connect', function(){
try {
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
} catch(e) {
console.log(e);
}
});
socket.emit("/" + device_id, "45678");
Any ideas?
UPDATE
Ran debug utility, results included as linked image below. Key thing I see is that engine.io tries to do an xhr poll, and gets a 503 response back from the server. (Obviously not a true 'temporary error' with the server as again, this all works from running client-side js in chrome).
debugging output image link
Solved this - issue was that the server I was connecting to required use of https, so I needed to add
{secure: true, rejectUnauthorized: false}
after the url to connect to.
Full working example:
const myemail = email#email.com;
const device_id = 12345;
io = require('socket.io-client');
var socket = io.connect('https://server.net:3000',{secure: true, rejectUnauthorized: false});
function doStuff(){
//Listener
socket.on('connect', function(){
try {
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
} catch(e) {
console.log(e);
}
});
socket.emit("/" + device_id, "003021");
}
doStuff();
I think the line causing the issue is :
var socket = io.connect('https://example.net:3000');
I managed to make a working example using this code :
const myemail = "email#gmail.com";
const device_id = '12345';
var socket = require('socket.io-client')('https://example.net:3000');
socket.on('connect', function(){
try{
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
}catch(e){ console.log(e); }
});
I am trying to connect between js client and python server in chrome extension platform, but getting error in the connection establishment.
It is important to note that the code worked in cmd test, but when I tried to make the connection in the chrome extension, it gets an error. So if someone had already deal with something similar, please check the code and help me to figure what is wrong with it.
I used serversocket module.
Here is the server:
clients = []
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
if self not in clients:
clients.append(self)
self.data = self.request.recv(1024).strip()
if self.data == "":
clients.remove(self)
print(self.data)
arr=self.data.split('~')
result=algo(arr)
self.request.send(result)
if _name_ == "__main__":
HOST, PORT = '127.0.0.1', 6169
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
print("hi")
# interrupt the program with Ctrl-C
server.serve_forever()
The alerts and some of the if are for checking
and the client:
var st="password11"+"~"+"www.google.com"+"~"+"1656226256";
//"wss://"+HOST+":"+PORT+"/"
if ('WebSocket' in window){
alert("websocket");
var socket = new WebSocket("wss://127.0.0.1:6169/", ['soap', 'xmpp']);
socket.onopen = function (evt) {
alert("connection opened");
socket.send(st);
};
socket.onmessage = function (evt) {
alert("Message from remote server : "+evt.data);
socket.close();
};
socket.onerror = function (evt) {
alert(evt.data);
};
socket.onclose = function (evt) {
alert("connection closed");
};
}
else {
alert("web socket is not supported")
}
i tumbled across websocket and http.
I have written below example:
var fs = require('fs');
var server = http.createServer(function(request, response) {
console.log ("HTTP Request created...");
// I am responding something here..
});
server.listen(1234, function() {
console.log((new Date()) + ' Server is listening on port 1234');
});
var WebSocketServer = require('websocket').server;
wsServer = new WebSocketServer({
httpServer: server
});
wsServer.on('request', function(re){
var conn = re.accept(null, re.origin);
console.log ("Accepted New Connection..");
conn.on('message', function(message) {
console.log ('message received' + message.utf8Data);
});
});
I tried in two ways connecting to this server.
1) Through Browser.
2) through node.js application
When I tried reaching this server through browser ex: http:IP:1234,
I get "HTTP Request received.." gets printed, where as when I try with
below code in Node.js, I do not see this message getting printed.
var WebSocket = require('ws')
ws = new WebSocket('ws://IP:1234');
ws.on('open', function() {
console.log ("WebSocket opened..");
ws.send('something');
});
ws.on('message', function(message) {
console.log('received: %s', message.data);
});
When I tried to connect to webserver through
ws = new WebSocket('ws://IP:1234');
why is It not getting through HTTP?. My basic understanding is Websocket is just an upgrade on top of HTTP, in that case, I would assume WebSocket(), in turn connectes through HTTP to the server right?. Or Am i confused?.
Websocket requests don't trigger a request event on the HTTP server instance (for which the function you pass to createServer is a listener).
If you want to watch websocket requests on the HTTP server, listen to upgrade events:
server.on('upgrade', function (req, socket, head) { ... });
I assume it's because http will handle the handshake/upgrade itself that this is done through a different event.
I get the message from client but in case of replying message, i tried many ways but no result .
My JavaScript Code is
var eb = new EventBus("http://localhost:8080/loginUrl");
eb.onopen = function () {
console.log("Connection Open")
};
eb.onclose = function () {
console.log("Connection Close")
};
eb.registerHandler("server-to-client", function (message) {
console.log('received a message: ' + message.body());
});
// publish a message
function sendMes(message){
console.log("Sending Message "+message);
eb.send("client-to-server",message,function(callback){
console.log("Received Message "+callback)
});
}
My Java Server Code is
Router router = Router.router(vertx);
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
SockJSHandler sockJSHandler = SockJSHandler.create(vertx);
BridgeOptions options = new BridgeOptions();
options.addInboundPermitted(new PermittedOptions().setAddress("client-to-server"));
options.addOutboundPermitted(new PermittedOptions().setAddress("server-to-client"));
sockJSHandler.bridge(options);
router.route("/loginUrl/*").handler(sockJSHandler);
EventBus eb = vertx.eventBus();
eb.consumer("client-to-server").handler(sockJSHand->{
System.out.println("Sending Message "+sockJSHand.body());//It prints the message from client
eb.send("server-to-client","Message");
});
How to reply back some message from server ?
Your code sample seems to be fine and almost looks like the chat server-client example application except that your should be using the EventBus#publish API instead of the EventBus#send API to allow the message to be dispatched among all registred handlers (all clients web browsers).
As per the Java docs:
EventBus publish(String address,
Object message)
Publish a message.
The message will be delivered to all handlers registered to the address.
An update of your server side code would be as follows:
Router router = Router.router(vertx);
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
BridgeOptions options = new BridgeOptions();
options.addInboundPermitted(new PermittedOptions().setAddress("client-to-server"));
options.addOutboundPermitted(new PermittedOptions().setAddress("server-to-client"));
SockJSHandler sockJSHandler = SockJSHandler.create(vertx).bridge(options);
router.route("/loginUrl/*").handler(sockJSHandler);
EventBus eb = vertx.eventBus();
eb.consumer("client-to-server").handler(
sockJSHand -> {
System.out.println("Sending Message "+ sockJSHand.body());//It prints the message from client
eb.publish("server-to-client", "Message");
}
);
I have opened the server.js and the address:http://localhost:8081 on my browser. But then a text "Upgrade Required" appeared at the top left conern of the website.
What is the problem of that? What else do I need to upgrade?
Here is the server.js:
var serialport = require('serialport');
var WebSocketServer = require('ws').Server;
var SERVER_PORT = 8081;
var wss = new WebSocketServer({
port: SERVER_PORT
});
var connections = new Array;
SerialPort = serialport.SerialPort,
portName = process.argv[2],
serialOptions = {
baudRate: 9600,
parser: serialport.parsers.readline('\n')
};
if (typeof portName === "undefined") {
console.log("You need to specify the serial port when you launch this script, like so:\n");
console.log(" node wsServer.js <portname>");
console.log("\n Fill in the name of your serial port in place of <portname> \n");
process.exit(1);
}
var myPort = new SerialPort(portName, serialOptions);
myPort.on('open', showPortOpen);
myPort.on('data', sendSerialData);
myPort.on('close', showPortClose);
myPort.on('error', showError);
function showPortOpen() {
console.log('port open. Data rate: ' + myPort.options.baudRate);
}
function sendSerialData(data) {
if (connections.length > 0) {
broadcast(data);
}
}
function showPortClose() {
console.log('port closed.');
}
function showError(error) {
console.log('Serial port error: ' + error);
}
function sendToSerial(data) {
console.log("sending to serial: " + data);
myPort.write(data);
}
wss.on('connection', handleConnection);
function handleConnection(client) {
console.log("New Connection");
connections.push(client);
client.on('message', sendToSerial);
client.on('close', function () {
console.log("connection closed");
var position = connections.indexOf(client);
connections.splice(position, 1);
});
}
function broadcast(data) {
for (c in connections) {
connections[c].send(data);
}
}
OK, websockets...
The "upgrade required" status marks the start of a websocket handshake. Normally your client sends this first to the WS server. The server answers in a pretty similar manner (details here : https://www.rfc-editor.org/rfc/rfc6455 ), and then proceed to pipe the actual data.
Here, you're opening a connection from your client as regular http, sending a simple GET. What you see on the screen is the server dumbly proceeding with an already corrupted handshake.
That's not how you open a WS client side connection. You don't usually open WS pages from the browser. It ought to be opened from a JavaScript call, such as new WebSocket(uri). So what you want is a regular http server on another port, that serves a page containing the necessary Javascript to open the actual WS connection and do something useful with its data. You'll find a clean example here : http://www.websocket.org/echo.html