nodejs not sending websocket to browser - javascript

i made a program that connects my java programm who sends data to my nodejs server using sockets and the nodejs server is supposed to send the received data to the browser using socket.io but there is a problem i do receive the data from java but the node server doesnt send it to the browser here is the code
// Create an instance of the Server and waits for a connexion
net.createServer(function(sock) {
// Receives a connection - a socket object is associated to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
// Add a 'data' - "event handler" in this socket instance
sock.on('data', function(data) {
//data was received in the socket and converting it into string
var textChunk = data.toString('utf8');
io.emit('message', textChunk); //socket.io is supposed to send the data to the browser
console.log(textChunk);
});
// Add a 'close' - "event handler" in this socket instance
sock.on('close', function(data) {
// closed connection
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
});
}).listen(PORT, HOST);

You may connect Java side (WebSocketServer) to Javascript side (browser) using github.com/TooTallNate/Java-WebSocket.
Java side:
final class Gateway extends WebSocketServer {
private WebSocket _webSocket;
Gateway( IDataManager dataManager, IConfiguration config) {
super( new InetSocketAddress( <host>, <port> );
new Thread( this ).start();
}
#Override
public void onOpen( WebSocket conn, ClientHandshake handshake ) {
final String request = handshake.getResourceDescriptor();
final String[] req = request.split( "[/=]" );
System.out.printf( "request: %s\n", Arrays.toString( req ));
_webSocket = conn;
...
}
public void publish( ... ) {
final ByteBuffer buffer = ByteBuffer.allocate( ... );
buffer.order( ByteOrder.BIG_ENDIAN );
buffer.putXXX( ... );
buffer.flip();
_webSocket.send( buffer );
}
#Override
public void onMessage( WebSocket conn, String buffer ) {
System.out.printf( "%s\n", buffer );
}
#Override
public void onMessage( WebSocket conn, ByteBuffer buffer ) {
try {
System.out.printf( "%d bytes received from %s",
buffer.remaining(), conn.getRemoteSocketAddress());
if( buffer.position() == buffer.limit()) {
buffer.flip();
}
buffer.order( ByteOrder.BIG_ENDIAN );
final byte xxx = buffer.getXxx();
...
}
catch( final Throwable t ) {
t.printStackTrace();
}
}
#Override
public void onError( WebSocket conn, Exception ex ) {
ex.printStackTrace();
}
#Override
public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
System.out.printf( "code: %d, reason: %s, remote: %s\n", code, reason, remote ? "true" : "false" );
}
}
Javascript side:
var webSocket = new WebSocket(
'ws://' + smoc.PROTOCOL_HOST +
':' + smoc.PROTOCOL_PORT +
'/viewID=' + $scope.viewID );
$scope.webSocket.binaryType = "arraybuffer";
$scope.webSocket.onmessage = function( evt ) {
...
};

Related

How to initiate websocket Server correctly?

I've set up a websocket server via php on a local MAMP PRO environment using Ratchet.
$server = IoServer::factory(
new Control(),
81,
'0.0.0.0'
);
Starting the server with root privileges (because I'm unable to get him up with other than root privileges (permission denied) )
php server.php
Establish a connection
telnet 192.168.2.106 81
Trying 192.168.2.106...
Connected to mmm.mrmedia.private.
Answers correctly
php server.php
New connection! (37)
But if I'm trying to connect to the server via JavaScript it's not going through the Handshake (ERR_CONNECTION_REFUSED after a couple of time).
New connection! (48)
Connection 48 sending message "GET / HTTP/1.1
Host: 192.168.2.106:81
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
Upgrade: websocket
Origin: http://192.168.2.106
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: de,de-DE;q=0.9,en;q=0.8,en-US;q=0.7,es;q=0.6,fr;q=0.5,it;q=0.4
Sec-WebSocket-Key: RH25+2UD8PQI+0A+VQWn4Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
The console outputs the following informations:
TIC TCP Conn Start [24126:0x7fdcc6f47c20]
TIC TCP Conn Event [24126:0x7fdcc6f47c20]: 3
TIC TCP Conn Failed [24126:0x7fdcc6f47c20]: 12:8 Err(-65554)
TIC TCP Conn Cancel [24126:0x7fdcc6f47c20]
Source server.php
use Ratchet\Server\IoServer;
use FluvalEdge\Control;
require dirname(__DIR__) . '/websocket-php-ratchet/vendor/autoload.php';
$server = IoServer::factory(
new Control(),
81,
'0.0.0.0'
);
$server->run();
Source Namespacing FluvalEdge
namespace FluvalEdge;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Control implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
// The sender is not the receiver, send to each client connected
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
// The connection is closed, remove it, as we can no longer send it messages
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
Calling the Client-Connection via
initWebsocket('ws://192.168.2.106:81', false, 5000, 5);
Source websocket.js
/**
* inits a websocket by a given url, returned promise resolves with initialized websocket, rejects after failure/timeout.
*
* #param url the websocket url to init
* #param existingWebsocket if passed and this passed websocket is already open, this existingWebsocket is resolved, no additional websocket is opened
* #param timeoutMs the timeout in milliseconds for opening the websocket
* #param numberOfRetries the number of times initializing the socket should be retried, if not specified or 0, no retries are made
* and a failure/timeout causes rejection of the returned promise
* #return {Promise}
*/
function initWebsocket(url, existingWebsocket, timeoutMs, numberOfRetries) {
timeoutMs = timeoutMs ? timeoutMs : 1500;
numberOfRetries = numberOfRetries ? numberOfRetries : 0;
var hasReturned = false;
var promise = new Promise((resolve, reject) => {
setTimeout(function () {
if(!hasReturned) {
console.info('opening websocket timed out: ' + url);
rejectInternal();
}
}, timeoutMs);
if (!existingWebsocket || existingWebsocket.readyState != existingWebsocket.OPEN) {
if (existingWebsocket) {
existingWebsocket.close();
}
var websocket = new WebSocket(url);
websocket.onopen = function () {
if(hasReturned) {
websocket.close();
} else {
console.info('websocket to opened! url: ' + url);
resolve(websocket);
}
};
websocket.onclose = function () {
console.info('websocket closed! url: ' + url);
rejectInternal();
};
websocket.onerror = function () {
console.info('websocket error! url: ' + url);
rejectInternal();
};
} else {
resolve(existingWebsocket);
}
function rejectInternal() {
if(numberOfRetries <= 0) {
reject();
} else if(!hasReturned) {
hasReturned = true;
console.info('retrying connection to websocket! url: ' + url + ', remaining retries: ' + (numberOfRetries-1));
initWebsocket(url, null, timeoutMs, numberOfRetries-1).then(resolve, reject);
}
}
});
promise.then(function () {hasReturned = true;}, function () {hasReturned = true;});
return promise;
};
/*
var ws_host_fluval = "fluvaledge.local";
var ws_port_fluval = "81";
var ws_server_fluval = "";
var ws_url_fluval = "ws://" + ws_host_fluval + ":" + ws_port_fluval + "/" + ws_server_fluval;
try
{
var socket_fluval = new WebSocket(ws_url_fluval);
// Handlerfunktionen definieren
socket_fluval.onopen = function()
{
// Willkommensnachricht an den Server senden
socket_fluval.send("Client hat Verbindung mit fluvaledge hergestellt");
};
socket_fluval.onmessage = function(msg)
{
console.log("Websocket: " + msg.data);
};
socket_fluval.onclose = function(msg)
{
console.log("Verbindung wurde getrennt");
};
}
catch(ex)
{
alert("Exception: " + ex);
}
*/
I think you are confusing plain sockets with WebSockets. Looking at the documentation it looks like you should not use IoServer but WsServer. The first seems to implement plain sockets while the second implements the WebSockets protocol which you are trying to access from Javascript.

unable to connect websocket(wss) from c#

In my application I am connecting chrome extension with windows application using websocket,
Javascript code :
var socket = new WebSocket('ws://172.xx.xxx.xx:11223/');
socket.onopen = function(event)
{
// Web Socket is connected, send data using send()
socket.send("hi..");
};
And C# code :
public static TcpListener Weblistener = null;
public static int selWebSocketPort = 0;
public static void StartListeningSahi()
{
Weblistener = new TcpListener(IPAddress.Parse(ipAddStr), portNumForSelenium);
try{
Weblistener.Start();
int TestingCycle = 100;
// Start listening for connections.
while (TestingCycle > 0){
TcpClient handler = Weblistener.AcceptTcpClient();
// An incoming connection needs to be processed.
lock (ClientSockets.SyncRoot){
if (handler != null){
int i = ClientSockets.Add(new ClientHandler(handler));
((ClientHandler)ClientSockets[i]).Start();
SelWebSocketPort = (handler.Client.RemoteEndPoint as IPEndPoint).Port;
NetworkStream networkStream = handler.GetStream();
Byte[] clientReq = new Byte[handler.Available];
networkStream.Read(clientReq, 0, clientReq.Length);
string headerRequest = Encoding.UTF8.GetString(clientReq);
SendResponseToWebSocket(handler, networkStream, headerRequest);
}
else
continue;
}
}
Weblistener.Stop();
}
catch (Exception e){
Console.WriteLine(e.ToString());
}
}
public static void SendResponseToWebSocket(TcpClient handler, NetworkStream networkStream, string headerRequest)
{
// generate accept key fromm client header request
var key = headerRequest.Replace("ey:", "`")
.Split('`')[1]
.Replace("\r", "").Split('\n')[0]
.Trim();
var responseKey = AcceptKey(ref key);
//create the response for the webclient
var newLine = "\r\n";
var response = "HTTP/1.1 101 Switching Protocols" + newLine
+ "Upgrade: websocket" + newLine
+ "Connection: Upgrade" + newLine
+ "Sec-WebSocket-Accept: " + responseKey + newLine + newLine;
//send respose to the webclient
Byte[] sendBytes = Encoding.ASCII.GetBytes(response);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
selWebSocketPort = (handler.Client.RemoteEndPoint as IPEndPoint).Port;
}
This is working fine for http site. But after that I changed the this javascript line var socket = new WebSocket('ws://172.xx.xxx.xx:11223/'); to var socket = new WebSocket('wss://172.xx.xxx.xx:11223/'); to support https sites, but unable to do so. I am getting below error on chrome -
WebSocket connection to 'wss://172.16.106.22:11223/' failed: WebSocket opening handshake timed out
The handshaking is getting failed as in the request header I am getting some junk value.
Am I missing something ?

WebSocket closing down on sending Base64 encode Strings

I'm trying to send a base64 encoded string (converted from a image) via websocket and this is working fine for me with a javascript client.
But if I use a java client (#clientEndPoint) instead, onMessage function is triggered once and the websocket connection immediately closes down. No errors.
Again, I tried sending plain strings from the server and the java client functions properly. But just not with base64 encoded strings.
I'm using Tomcat 7.0.69 and below are the code snippets:
Server End Point:
if (imageToBeSend != null) {
encodedImage = new sun.misc.BASE64Encoder().encode(imageToBeSend);
session.getBasicRemote().sendText(encodedImage);
}
Java client:
#ClientEndpoint
public class SomeClass {
CountDownLatch latch = new CountDownLatch(1);
private Session session;
String msg;
#OnOpen
public void open(Session session) {
this.session = session;
//some stuff
}
#OnClose
public void close(Session session) {
System.out.println("Closing the connection");
}
#OnError
public void onError(Throwable error) {
System.out.println("!!!ERROR!!!!!" + error);
error.printStackTrace();
}
#OnMessage
public void handleMessage(String message, Session session) throws IOException {
System.out.println("got the json string "+message.length());
// more stuff
}
Here the handle message is invoked one time and the corresponding sysout is printed and then immediately onClose is invoked. onError is never invoked.

How to send/read java ByteBuffer (websocket) from javascript client onmessage function

Server code in java:
#OnMessage
public void onMessage(Session session, ByteBuffer message) {
if (session.isOpen()) {
String msg = new String(message.array());
System.out.println("Message from " + session.getId() + ": " + msg);
try {
session.getBasicRemote().sendBinary(ByteBuffer.wrap("I have got the message".getBytes()));
} catch (IOException ioe) {
System.out.println(ioe.toString());
}
} else {
System.out.println("Session is not open");
}
}
Client code in Javascript:
webSocket = new WebSocket("ws://192.168.10.1:2525/myChat/chat");
webSocket.binaryType = 'arraybuffer';
webSocket.onopen = function(event) {
updateOutput("Connected!");
connectBtn.disabled = true;
sendBtn.disabled = false;
};
webSocket.onmessage = function(event) {
updateOutput(event.data);
};
Note:
Server code works fine when I use it with Web GL client as it is send Binary data.
Javascript client works fine when I read String data in Server end
(from java code):
#OnMessage
public void onMessage(Session session, String message) {}
Thanks in advice for any comments.
I've found the solution to the issue.
I have used ByteBuffer.js library to send/read data of ByteBuffer type in JavaScript:
webSocket.binaryType = "arraybuffer";
In the function onmessage for reading data:
var d = event.data;
console.log(d.toString());
In the function send for sending data:
var bb = dcodeIO.ByteBuffer.wrap(text);
webSocket.send(bb.toArrayBiffer());

Why is this node.js tcp server not writing back to Java client until it closes?

Here is an example of a tcp server written in node.js I found:
net.createServer(function(sock) {
// We have a connection - a socket object is assigned to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
// Add a 'data' event handler to this instance of socket
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
// Write the data back to the socket, the client will receive it as data from the server
sock.write('You said "' + data + '"');
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
I am trying to use this as a basis for a tcp server which will have to handle multiple incoming connections at the same time. Here is a Java program I wrote to test this:
public static final String MESSAGE = "Hellow world";
public static Semaphore networkLock;
public static void main(String[] args)
{
//writeMessage(MESSAGE);
Thread[] threadPool = new Thread[10];
networkLock = new Semaphore(1);
for (int i = 0; i < threadPool.length; i++)
{
threadPool[i] = new Thread(new Runnable() {
#Override
public void run() {
writeMessage(MESSAGE);
}
});
threadPool[i].start();
}
}
public static void writeMessage(String test)
{
try {
if(sock == null || sock.isClosed())
sock = new Socket(HOST, PORT);
DataOutputStream out =
new DataOutputStream(sock.getOutputStream());
System.out.println("Writting message");
//networkLock.acquire();
out.writeUTF(test);
//networkLock.release();
BufferedReader in = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
System.out.println("Waiting for reply");
String input = in.readLine();
System.out.println(input);
// in.close();
// out.close();
// sock.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I start the client, the only output I get from the client is a "Writting message" and "Waiting for reply" a bunch of times. When I shut down the server, I finally get the responses of You said " Hellow world" along with a null or two thrown in usually. As for the server, it prints out the two print statements just fine. Do you think someone could help me out here?
The Java client is using in.readLine() which looks for a newline character in the input stream. However, the server is not writing a newline to the client socket.
So change this:
sock.write('You said "' + data + '"');
to this:
sock.write('You said "' + data + '"\n');

Categories