I try to connect my PC with node.js and Websocket to a embedded system that communicates via JSON strings. Previously i was convinced that an xhr request would be sufficent to do this, but i have learned using wireshark, that there is to much overhead using xhr, and i am not able to include an end of line or carriage return to the JSON string, that is required by the embedded system as I get a invalid or unexpected token error everytime i add the \r in the string.
('{"id":7, "Client_ID":"webinterface", "method":"OutBit", "param":
[10,1], "jsonrpc":"2.0", "protocol":"2X"}\r');
I have searched for examples on stackoverflow, and it seems that websocket can be used to send and receive raw data, but im not sure if this code is set up correctly and if its meant to be used by a client PC.
The embedded system only needs a JSON String with an end of line character. It sends back a JSON String with updated values after connecting. I cannot change the behaviour of the embedded system communication as its custom made hardware.
var WebSocket = require('ws')
var ws = new WebSocket("ws://1.100.0.280:9398");
ws.send('{"id":7, "Client_ID":"webinterface", "method":"OutBit", "param":
[10,1], "jsonrpc":"2.0", "protocol":"2X"\r}');
with the code above I receive a:
WebSocket is not open: readyState 0 (CONNECTING) error.
Is it even possible to use Websocket with a non websocket / embedded System Server?
Related
There is a very good utility called ttyd, which allows you to run a console application on your computer and display this console in the browser.
After startup, the utility starts an http web server on the specified port and when accessing localhost, a website with a web application that connects using web sockets to localhost:<port>/ws, and already with the help of them there is communication between the web application and the ttyd agent running on the computer.
I want to implement a client for ttyd in c#. I studied with the help of chrome tools what data the web application sends before receiving the data output to the console. This is just a string: {"authToken":"","columns":211,"rows":46} and tried to repeat the same actions in the c# client. But for some reason, no data from ttyd is returned to me.
Comparing the data output by ttyd to its console in the OS itself, it can be seen that it does not even create a process when accessing from my client.
Here is the code I use with the Websocket.Client package
var exitEvent = new ManualResetEvent(false);
var url = new Uri("ws://localhost:7681/ws");
using (var client = new WebsocketClient(url))
{
client.ReconnectTimeout = TimeSpan.FromSeconds(30);
client.ReconnectionHappened.Subscribe(info =>
Console.WriteLine($"Reconnection happened, type: {info.Type}"));
client.MessageReceived.Subscribe(msg => Console.WriteLine($"Message received: {msg}"));
client.Start();
Task.Run(() => client.Send("{\"AuthToken\":\"\",\"columns\":211,\"rows\":46}"));
exitEvent.WaitOne();
}
I have absolutely no idea how to get ttyd to send data to my client. Do you have any idea what action the browser is doing I'm missing in my c# client?
I tried different libraries for web sockets in c#, and also used postman with copying all the headers that the original web application sends to the ttyd agent, but this does not change anything. That is, ttyd, something is fundamentally interfering, as if my web client is not doing something that the browser is doing.
I just set up a small TCP-socket server in python3, which waits for a connection, sends a small encoded text and waits for data from the client.
Python-Code:
import socket
sock = socket.socket()
sock.bind(("0.0.0.0", 20000))
sock.listen(5)
while True:
Client, address = sock.accept()
Client.send("ping".encode())
print(Client.recv(1024).decode()) # Here I want to receive data from the client
Client.close()
At the end, there should be a browser interface which can communicate with the python backend with JQuery or just something that receive and send (With data!) sockets.
Thank you :D
EDIT:
Forgot to say that I can receive the text in a browser, I just need to know how to send data back.
if you need to connect to a NodeJS javascript environment then you should take a look at this native package
https://nodejs.org/api/net.html#class-netsocket
if you need to connect to a browser javascript environment then you should take a look at WebSockets
Python: https://websockets.readthedocs.io/en/stable/#:~:text=websockets%20is%20a%20library%20for,an%20elegant%20coroutine%2Dbased%20API.
Javascript https://developer.mozilla.org/es/docs/Web/API/WebSockets_API
I am in the process of testing a migration of data from an already existing server to a new server.
Part of that is checking to make sure JWTs saved on the old server are being sent to the new server correctly. The process is to fetch tokens from the old server to the test server, and then send them to the new server to check to see if they exist. The old server sends unsigned JWTs over to my test server, and then I need to sign them in order to check them against the new server.
In order to get a signature for these tokens, running the following code:
// Get the object represented by the token
this.token = jwt.decode(`${this.unsignedToken}.a`)
// Turn the object into a signed token string
this.signedToken = jwt.sign(this.token, this.tokenSecret)
I concatenated the '.a' onto the end of the unsignedToken because jwt.decode needs a "signed"" token in order to get the data back.
The problem I am having is that the unsignedToken and the signedToken don't have the same payload section of the JWT, even though they both decode to the exact same object. Because of that, the endpoint the signedTokens are sent to isn't able to match them up to what is on that server properly.
When I manually check the unsigned token against the new server's database, it does exist, but because the signedToken isn't the same string before the signature, the test process won't work.
Am I doing something wrong?
Edit:
Answer:
When I manually decoded the two tokens as base64 at https://www.base64decode.org/, I discovered that the unsignedToken included a URL that looked like "https:\/\/" while the signedToken's url was "https://".
For anyone out there coming across this as well, my final solution was how I signed token:
this.signedToken = jwt.sign(JSON.stringify(this.token).replace(/\//g, '\\/'), this.tokenSecret)
When I manually decoded the two tokens as base64 at https://www.base64decode.org/, I discovered that the unsignedToken included a URL that looked like "https:\/\/" while the signedToken's url was "https://".
For anyone out there coming across this as well, my final solution was how I signed token:
this.signedToken = jwt.sign(JSON.stringify(this.token).replace(/\//g, '\\/'), this.tokenSecret)
I try to send messages from PHP server to Node.js server. The purpose of the Node.js server is to convey the message forward using the Socket.io and Express.
$NodePage = file_get_contents($NodeServer. "/index.html?&message=". $message);
The server always returns empty string and do not send a message. Same URL in browser working Ok and a message is sent correctly. I also try redirect command.
header("Location: http://xxxxxxx.fi/index.html?message=". $message);
Also returns empty string. Working Ok in web browser. I make PHP calls from C# client.
HtmlWeb web = new HtmlWeb();
string tempURL = _url + _htmlMessageStr +
"?message=" + msg.fullMessage) ;
HtmlDocument doc = web.Load(tempURL);
HtmlNodeCollection tags =
doc.DocumentNode.SelectNodes(_nodeText);
_retVal = parse(tags[0].InnerHtml);
Any other data is ok from PHP, except node data (empty string). I tried to retrieve data from other Node.js servers and it restore the data correctly. Something is wrong with my Node.js server but what? Server is hosted by hosting company. The server does not run anything other than Node.js.
This needs to be enabled in the php.ini. The option you are searching for is "allow_url_fopen" and set it to true.
http://php.net/manual/en/filesystem.configuration.php
I found the problem. You can not use the file_get_contents command to connect Socket.io to the Node.js server. You need to connect to the socket.io.
This article explains how to do it.
enter link description here
I'm working on creating a websocket server via python (I'm kinda new to python) and I've made a significant progress, but I am unable to send data to the web browser. I can establish a connection and receive data from the browser, but I cannot send back data. The browser just ignores it. I would assume that if the browser received a package that didn't follow the specifications, it would terminate the connection, but the connection stays active.
Here is the method I am using to encode the data into the frame:
def encode_message(data):
frame = "\x81"
size = len(data)
if size * 8 <= 125:
frame += chr(size)
else:
raise Exception("Uh, oh. Strings larger than 125 bits are not supported")
return frame + data
I am sending the data using sock.sendall(framed_data). What could be the problem? The data for a message like "yo" ends up being 10000001 00000010 01111001 01101111 (spaces added for improved readability). Why doesn't the browser accept a message like this? Doesn't it follow the guidelines outlined in the specification? I am trying to support the most recent websocket version which I believe to be version 13. I am using python version 2.7.3.
I have tried to look at python websocket libraries' source code, but all of them seem to implement a deprecated version of the websocket protocol that has been shown to have vulnerabilities.
Here is the code that calls the function above:
def send(data):
frame = encode_message(data)
print "Sending all..."
sock.sendall(frame) #Socket that handles all communications with client
print "Frame sent :)"
return
I also downloaded wireshark to sniff the packages sent between the server and the socket. The packages sent by my server are identical to those sent from a server that is accepted by the browser. I couldn't see any difference at all. (I looked directly at the hex source)
The second byte of your transmitted message (and the length check in your code) looks wrong. The length of a message is in bytes, not bits.
From RFC6455 ยง5.2 (my emphasis)
Payload length: 7 bits, 7+16 bits, or 7+64 bits
The length of the "Payload data", in bytes: if 0-125, that is the
payload length.
The reason that nothing is received in the browser is that your message claims to have a 16 byte body. The browser will read the 2 additional bytes you send then block waiting for another 14 bytes that it expects but you don't send.
If you change the second byte to the number of bytes in the message - 0x2 or 00000010 binary - then things should work.
I finally figured out the problem! It took hours of unfun debugging and messing with my code. After closely examining the packages sent back and forth between the server and client I finally realized that there was a problem with my server's connection upgrade response. Whenever it computed a hash, it also added a \n to the end of it. That resulted in a \n\r\n at the end of one of the lines. The client interpreted that as the end of that transmission and everything that followed was parsed using WebSocket protocol. I had another line after that in the header, so it totally messed up my communications with the client. I could still read from the client, but if I tried to write to the client, the data would get messed up.