i have a service, which uses QWebSocketServer. My server is able to handle client requests and send several events to client (without any request, it is important). I've tested my server with QWebSocket class like shown in Qt example. All works perfectly.
Now i want to implement frontend in js. And i've faced with one thing which i cannot understand. If client sends request to server, server's answer can be received on client side, but if server sends data without client request, i'm not able to receive this data.
In my js script i have usual code:
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
So, why i can't receive data from server without request and what should i do for getting the ability to receive that?
server has been sending messages from another thread, that was the cause of problem
Related
I have a WebSocket server that I am trying to make and I can't figure out why it is not connecting.
index.html(client):
<p id="status">Connecting...</p>
<input id="message" />
<button id="submit">Send</button>
<script>
var s = new WebSocket("wss://StarliteServer.cs641311.repl.run:8000", ["soap", "wamp"]);
s.onopen = function() {
document.getElementById("status").innerHTML="Connected";
}
document.getElementById("submit").addEventListener("click", function() {
s.send(document.getElementById("message").value);
});
s.onmessage = function(e) {
alert(e.data);
}
s.onclose = function(e) {
document.getElementById("status").innerHTML = "ERROR: "+e.code
}
</script>
app.js
var http = require('http');
http.createServer(function(req, res) {
req.onopen = function() {
console.log("OPENING CONNECTION");
res.writeHead(200);
}
req.on('data', function(e) {
res.write(e);
});
req.on('close', function() {
console.log('CONNECTION CLOSED');
});
}).listen(8000);
A websocket client requires a websocket server to connect to. While all webSocket connections do start with a plain http request, the server must then "upgrade" the connection to the webSocket protocol and the server must be able to speak that webSocket protocol. If not, the client will drop the connection since the server fails to support the proper protocol.
There are multiple websocket server libraries for node.js in NPM. Pick one of those and add it to your server. If your server intends to also serve as a regular http server, you can share the same http server with the websocket server. The webSocket server code will examine each incoming request and pick off the ones that show that they represent the initiation of a webSocket connection and it will take them over from there.
To give you an idea what a webSocket server must do, you can see this article on writing websocket servers. I'm not suggesting you write your own (too much time spent on protocol detail), but this will certainly explain why a plain http server won't suffice for a webSocket connection.
I have an angular application needing to subscribe to a websocket for incoming data.
On the angular side, in a service I have
setContextChannel(channel) {
this.contextWS = new WebSocket(channel);
that = this;
this.contextWS.onmessage = function(event) {
console.log('ws', event.data);
that.patientID = event.data;
};
this.contextWS.onerror = function(event) {
console.log('ws error', event);
}
}
and on the mock server side, I have a typescript node server that creates the socket as follows:
import {Server} from "ws";
var wsServer: Server = new Server({port: 8085});
console.log('ws on 8085');
wsServer.on('connection',websocket => websocket.send('first pushed message'));//////
my question is how to use the wsServer to send messages?
I'm not sure what are you asking about. This line is correct:
wsServer.on('connection',websocket => websocket.send('first pushed message'));
If you want to keep sending messages to all connected clients, you need to either use the property wsServer.clients to send messages to each connected client, or store the references to each connected client (the websocket variable in your code) in an array and then send the messages to each client using forEach().
Take a look at this code sample: https://github.com/Farata/angular2typescript/blob/master/chapter8/http_websocket_samples/server/bids/bid-server.ts
So I am trying to make some sort of connection between my Java app and my Web app, I looked up websockets and they look really simple and easy to use :). And I created myself a Java Server, which uses the ServerSocket class.
Now the problem is I am able to connect to the server from the web, with the websocket, but I am unable to send data to the server... but when I tried to send data from a Java Client it worked fine... what might be the problem?
My Java/Scala (I followed this tutorial: https://www.tutorialspoint.com/java/java_networking.htm) server:
class Server(val port: Int) extends Thread {
private val serverSocket = new ServerSocket(port)
override def run(): Unit = {
try {
while(true) {
println("Waiting for client on port: " + serverSocket.getLocalPort)
val server = serverSocket.accept()
println(server.getRemoteSocketAddress)
val in = new DataInputStream(server.getInputStream())
println(in.readUTF())
val out = new DataOutputStream(server.getOutputStream())
out.writeUTF("Hello world!")
server.close()
}
} catch {
case s: SocketTimeoutException => println("Connection timed out!");
case e: Exception => e.printStackTrace()
}
}
}
My web js (I followed https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications ):
/**
* Created by samuelkodytek on 20/12/2016.
*/
var conn = new WebSocket('ws://127.0.0.1:8080');
conn.onopen = function(e) {
console.log("Connection established!");
conn.send("Hello!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
A web socket server is not the same thing as a simple socket server. A server that offers web sockets must first offer HTTP or HTTPS services because the web socket is established when a web client sends an HTTP request with an Upgrade option and special fields for establishing the web socket. Even after the web socket is established, the connection still does not behave exactly like a regular socket. The Web Socket protocol uses frames to send or receive data. This is all considerably different from what you seem to expect.
One other thing that you should be aware of is that the browser will enforce the rule that the web socket must come from the same host as the page that is attempting to establish the web socket (the same protocol, address, and TCP port).
I have configured my websocket connection following the example:
https://github.com/netty/netty/tree/3/src/main/java/org/jboss/netty/example/http/websocketx/sslserver
This all works, i have the browser connecting to a secured websocket using https address.
$(document).ready(function () {
var location = "wss://localhost:9999/websocket"
ws = new WebSocket(location);
ws.onopen = function(event) {
}
ws.onclose = function(event) {
}
ws.onmessage = function(event) {
}
});
I want to connect to this page that makes the websocket connection using http?... is that possible ?... I have tried this, and it doesn't seem to work.. so im not sure...
I have read that it is possible to create a WSS connection when regardless of going to the page using http or https?.. is this correct?
I want to provide a meaningful error to the client when too many users are connected or when they're connecting from an unsupported domain, so...
I wrote some WebSocket server code:
var http = require('http');
var httpServer = http.createServer(function (request, response)
{
// i see this if i hit http://localhost:8001/
response.end('go away');
});
httpServer.listen(8001);
// https://github.com/Worlize/WebSocket-Node/wiki/Documentation
var webSocket = require('websocket');
var webSocketServer = new webSocket.server({ 'httpServer': httpServer });
webSocketServer.on('request', function (request)
{
var connection = request.reject(102, 'gtfo');
});
And some WebSocket client code:
var connection = new WebSocket('ws://127.0.0.1:8001');
connection.onopen = function (openEvent)
{
alert('onopen');
console.log(openEvent);
};
connection.onclose = function (closeEvent)
{
alert('onclose');
console.log(closeEvent);
}
connection.onerror = function (errorEvent)
{
alert('onerror');
console.log(errorEvent);
};
connection.onmessage = function (messageEvent)
{
alert('onmessage');
console.log(messageEvent);
};
All I get is alert('onclose'); with a CloseEvent object logged to the console without any status code or message that I can find. When I connect via ws://localhost:8001 the httpServer callback doesn't come into play, so I can't catch it there. The RFC suggests I should be able to send any status code other than 101 when there's a problem, but Chrome throws an error in the console Unexpected response code: 102. If I call request.reject(101, 'gtfo'), implying it was successful I get a handshake error, as I'd expect.
Not really sure what else I can do. Is it just not possible right now to get the server response in Chrome's WebSocket implementation?
ETA: Here's a really nasty hack in the mean time, I hope that's not what I have to end up doing.
var connection = request.accept(null, request.origin);
connection.sendUTF('gtfo');
connection.close();
I'm the author of WebSocket-Node and I've also posted this response to the corresponding issue on GitHub: https://github.com/Worlize/WebSocket-Node/issues/46
Unfortunately, the WebSocket protocol does not provide any specific mechanism for providing a close code or reason at this stage when rejecting a client connection. The rejection is in the form of an HTTP response with an HTTP status of something like 40x or 50x. The spec allows for this but does not define a specific way that the client should attempt to divine any specific error messaging from such a response.
In reality, connections should be rejected at this stage only when you are rejecting a user from a disallowed origin (i.e. someone from another website is trying to connect users to your websocket server without permission) or when a user otherwise does not have permission to connect (i.e. they are not logged in). The latter case should be handled by other code on your site: a user should not be able to attempt to connect the websocket connection if they are not logged in.
The code and reason that WebSocket-Node allow you to specify here are an HTTP Status code (e.g. 404, 500, etc.) and a reason to include as a non-standard "X-WebSocket-Reject-Reason" HTTP header in the response. It is mostly useful when analyzing the connection with a packet sniffer, such as WireShark. No browser has any facility for providing rejection codes or reasons to the client-side JavaScript code when a connection is rejected in this way, because it's not provided for in the WebSocket specification.