问题
Let me give a little background on what I am trying to accomplish.
I have a device(chip and pin Terminal) that has a local IP address, It has been programmed to receive certain data and process it.
example: I send the string "05"
in hex "30 35"
and the terminal reads that and will restart.
I have tried using SockJS-Client as well as the built in WebSockets.
However using Websockets I notice that the browser is sending:
GET / HTTP/1.1
Host: IP:PORT
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: MYIP
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Sec-WebSocket-Key: A1CeTMFnQCZv4GNZbLFnyQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
When my code looks like this:
var exampleSocket = new WebSocket("ws://IP:PORT");
exampleSocket.send("05");
If I change the code to this:
var exampleSocket = new WebSocket("wss://IP:PORT");
exampleSocket.send("05");
I just get 3 tags that are sent: SYN(0x0016) ETX(0x0003) SOH(0x0001)
Now I'm not sure if you need to have a WebSocket Sever to be able to interpret the incoming data.
SockJS does the same thing by sending extra information about itself and the broswer:
GET /info?t=1452272641278 HTTP/1.1
Host: IP:PORT
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Origin: MYIP
Accept: */*
Referer: MYIP
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
So I guess my question is. Is there a way to just send exactly what I want? without any extra data?
I have completed this in Objective-C as well as C#, I'm just not sure if javascript can do this?
Please ask if anything is unclear and I will try to clarify.
回答1:
You cannot make a plain TCP connection from Javascript in a browser that will allow you to send data in your own data format or protocol. The browser simply does not support that.
It only allows you to make Ajax requests and WebSocket connections. Both Ajax and WebSocket requests start life as an HTTP request. In the case of the webSocket request, the HTTP request can then be "upgraded" to the webSocket protocol after both sides agree, but the initial data sent to the server will be a legal HTTP request. You can see this MDN reference for a whole outline of how the webSocket protocol works from connection to actual packet format. Even once it is upgraded to the webSocket protocol, then it must use the webSocket framing format for all data which is described here.
Here's an outline of the webSocket data frame format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
So, unless your endpoint speaks HTTP or the webSocket protocol, you cannot connect directly to it from browser Javascript.
What you are seeing in your question as the initial HTTP request is the beginnings of a webSocket connection. That's how it works.
If you use Javascript in a non-browser environment such as node.js, you can use the the "net" module to create a plain TCP socket which you can then use whatever protocol you want with.
回答2:
I eventually found a solution.
What I had to do was create a windows application that will act as a websocket server.
When installing the program it will create a URI Scheme to be able to call itself from a link like myapp://start
Here is the code to edit the registry to add a custom URI Scheme:
static void Main(string[] args) {
try {
// SET PATH OF SERVER
String path = Environment.GetCommandLineArgs()[0];
// GET KEY
RegistryKey key = Registry.ClassesRoot.OpenSubKey("myApp");
// CHECK FOR KEY
if (key == null) {
// SET KEY
key = Registry.ClassesRoot.CreateSubKey("myApp");
key.SetValue(string.Empty, "URL: myApp Protocol");
key.SetValue("URL Protocol", string.Empty);
// SET COMMAND
key = key.CreateSubKey(@"shell\open\command");
key.SetValue(string.Empty, path + " " + "%1");
//%1 represents the argument - this tells windows to open this program with an argument / parameter
}
// CLOSE
key.Close();
} catch (Exception ex) {
Console.WriteLine(ex.Message);
Console.ReadKey();
}
}
Then in the browser it will call that url which starts the program. The websocket will get created and send it to the localhost:port server program that is running.
The windows program will do everything to get the data then send it as raw tcp/ip bytes to the terminal. Once the terminal sends data back to the windows program, the windows program will then forward that back to the websocket for the browser to handle the information.
The windows program then will kill all connections and quit.
回答3:
Have you tried to use like this:
var exampleSocket = new WebSocket('wss://IP:PORT', ['soap', 'xmpp']);
// When the connection is open, send some data to the server
exampleSocket.onopen = function () {
exampleSocket.send('05');
};
// Log errors
exampleSocket.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
exampleSocket.onmessage = function (e) {
console.log('Server: ' + e.data);
};
hope I could be helpfull!
来源:https://stackoverflow.com/questions/34682481/is-there-a-way-to-do-a-tcp-connection-to-an-ip-with-javascript