WebSocket - Javascript client says connected, but Java server doesn't - javascript

I have very simple code, yet, it doesn't work perfectly.
In Java server it just says Hello and Bye when opening and closing a connection and prints a sent message:
#ApplicationScoped
#ServerEndpoint("/tictactoe")
public class WebSocketServer {
private Logger logger = Logger.getLogger(this.getClass().getName());
#OnOpen
public void open(Session session) {
logger.info("WebSocket: Hello - " + session.getId());
}
#OnClose
public void close(Session session) {
logger.info("WebSocket: Farewell - " + session.getId());
}
#OnMessage
public void messageHandler(String message, Session session) {
logger.info("WebSocket: New Message - " + message);
}
}
In JavaScript it does pretty much the same like in the server and sends a message when clicking a button:
var socket = new WebSocket("ws://localhost:8080/TicTacToeZTP/tictactoe");
socket.onopen = function (event) {
console.log("WebSocket: Connected");
console.log("WebSocket: " + checkConnection(socket.readyState));
};
socket.onclose = function (event) {
console.log("WebSocket: Disconnected");
};
socket.onerror = function(event) {
console.log("WebSocket: Error");
};
socket.onmessage = function (event) {
console.log("WebSocket: New Message - " + event.data);
};
function checkConnection(readyState) {
switch(readyState){
case 0: return "CONNECTING";
case 1: return "OPEN";
case 2: return "CLOSING";
case 3: return "CLOSED";
default: return "UNDEFINED";
}
}
$("#send").click(function () {
var msg = {
type: "message",
text: "zaladzi"
};
socket.send(JSON.stringify(msg));
});
Now its time for a problem. After refreshing a page with an established connection.
What the script says:
WebSocket: Connected
WebSocket: OPEN
But the server doesn't open a new one. In fact I sometimes need a couple of refreshes to open a new connection on the server.
What the server says:
Info: WebSocket: Hello - 29538711-f815-4c59-835e-97aaaac1d112
Info: WebSocket: Farewell - 29538711-f815-4c59-835e-97aaaac1d112
I'm using Payara 4.1 server. How to solve this issue?
TL/DR JavaScript client says connection is opened, but Java client says there is no such a connection.

This is likely due to a bug in Payara Server which is fixed https://github.com/payara/Payara/issues/536 in that bug OnOpen isn't called in the server when a socket is reused.
You could try a pre-release version of Payara to ensure it is fixed. Pre-release builds are available from the Payara website a new pre-release build is created and uploaded every time their Jenkins CI server completes a GitHub merge build.

Related

Javascript Websocket fails to receive TCP data

I'm trying to receive json data from an ESP32 via TCP to a website hosted thru WAMP (localhost -> ESP32 IP address on local network is 10.11.125:23). Below is my javascript function. My browser (Firefox Developer) generates a "SecurityError: The operation is insecure" when executing the line var connection = new webSocket('ws://10.11.13.125:23'). What am I missing??
function openWebsocket() {
console.log("open Websocket.....");
var connection = new WebSocket('ws://10.11.13.125:23');
connection.onerror = function(error) {
$("#Connection").html("Connection Error");
console.log("Websocket Error: " + error);
}
connection.onopen = function(evt) {
$("#Connection").html("Connected");
}
connection.binaryType = 'arraybuffer';
connection.onmessage = function(evt) {
console.log("Server: " + evt.data.byteLength);
}
console.log("ReadyState: "+connection.readyState);
}
I found the problem. The Chromium browser yields a more descriptive error message. Port 23 is not available. Switched over to
var connection = new WebSocket('ws://10.11.13.125:80');
and voila, everything works as expected.
Sorry for posting about an issue that in the end I found the solution for myself.

Implementing RabbitMQ in Chrome Kiosk/Extension/Apps and Web Browsers

I'm developing internal applications that require push notifications but we cannot use outside services. I have started to work with RabbitMQ and have it working flawlessly inside of .NET Core. When trying to implement it the same thing with javascript I am not getting the same results.
I developed test clients in C#. I developed a client in javascript. I can make a successful connection but data is not arriving.
In C# I am using:
string e = Console.ReadLine();
Console.WriteLine("Enter a message (blank for test msg)");
string message = Console.ReadLine();
var factory = new ConnectionFactory() { HostName = "10.222.2.160" };
factory.UserName = "Test";
factory.Password = "TestPassword";
factory.VirtualHost = "/";
using (var connection = factory.CreateConnection("TestChannel"))
using (var channel = connection.CreateModel())
{
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: e,
routingKey: "",
basicProperties: null,
body: body);
Console.WriteLine(" [x] Sent {0}", message);
}
In Javascript:
var wsbroker = "10.222.2.160"; // mqtt websocket enabled broker
var wsport = 15675; // port for above
var client = new Paho.MQTT.Client(wsbroker, wsport, "/ws/",
"test");
client.onConnectionLost = function (responseObject) {
console.log("CONNECTION LOST - " + responseObject.errorMessage);
};
client.onMessageArrived = function (message) {
console.log("RECEIVE ON " + message.destinationName + " PAYLOAD " + message.payloadString);
};
var options = {
userName: "Test",
password: "TestPassword",
timeout: 3,
keepAliveInterval: 30,
onSuccess: function () {
console.log("CONNECTION SUCCESS");
client.subscribe('test', { qos: 1 });
},
onFailure: function (message) {
console.log("CONNECTION FAILURE - " + message.errorMessage);
}
};
if (location.protocol == "https:") {
options.useSSL = true;
}
console.log("CONNECT TO " + wsbroker + ":" + wsport);
client.connect(options);
I need to be able to connect to rabbitmq from javascript (non-node, chrome kiosk application/chrome extension). However, I'm not sure I am "understanding" RabbitMQ. Pointing me in the right direction would help a girl out. Thanks!
You're publishing without a routing key here:
channel.BasicPublish(exchange: e,
routingKey: "",
basicProperties: null,
body: body);
Ensure that the test queue exists, then change routingKey to test in your publisher, and use the exchange named amq.direct.
You should read the RabbitMQ introduction available here to get familiar with how exchanges, queues, routing keys and bindings interact:
https://www.cloudamqp.com/blog/2015-05-18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.

How to connect IBM Watson IOT using Paho MQTT javascript client?

I am trying to connect IBM Watson IoT platform using Paho MQTT Javascript client as mentioned in the below example code.
var client = new Messaging.Client("myOqgId.messaging.internetofthings.ibmcloud.com", 8883, "myclientid_" + parseInt(Math.random() * 100, 10));
//Gets called if the websocket/mqtt connection gets disconnected for any reason
client.onConnectionLost = function (responseObject) {
//Depending on your scenario you could implement a reconnect logic here
alert("connection lost: " + responseObject.errorMessage);
};
//Gets called whenever you receive a message for your subscriptions
client.onMessageArrived = function (message) {
//Do something with the push message you received
$('#messages').append('<span>Topic: ' + message.destinationName + ' | ' + message.payloadString + '</span><br/>');
};
//Connect Options
var options = {
userName: API-Key here,
password: Auth token here,
timeout: 3,
//Gets Called if the connection has sucessfully been established
onSuccess: function () {
alert("Connected");
},
//Gets Called if the connection could not be established
onFailure: function (message) {
alert("Connection failed: " + message.errorMessage);
}
};
//Creates a new Messaging.Message Object and sends it to the HiveMQ MQTT Broker
var publish = function (payload, topic, qos) {
//Send your message (also possible to serialize it as JSON or protobuf or just use a string, no limitations)
var message = new Messaging.Message(payload);
message.destinationName = topic;
message.qos = qos;
client.send(message);
}
But not able to connect.
I am getting this error:
WebSocket connection to 'ws://myOrgIdXYZ.messaging.internetofthings.ibmcloud.com:8883/mqtt' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
Please anybody out there who tried connecting IBM Watson IoT using Paho Mqtt client.
Thank you all for your responses. Based on all responses I have made changes in my code.
<script type="text/javascript">
var clientId = 'a:myOrgId:'+Math.random().toString(16).substr(2, 8);
var client = new Messaging.Client("myOqgId.messaging.internetofthings.ibmcloud.com", 1883, clientId);
//Gets called if the websocket/mqtt connection gets disconnected for any reason
client.onConnectionLost = function (responseObject) {
//Depending on your scenario you could implement a reconnect logic here
alert("connection lost: " + responseObject.errorMessage);
};
//Gets called whenever you receive a message for your subscriptions
client.onMessageArrived = function (message) {
//Do something with the push message you received
$('#messages').append('<span>Topic: ' + message.destinationName + ' | ' + message.payloadString + '</span><br/>');
};
//Connect Options
var options = {
userName: API-Key here,
password: Auth token here,
timeout: 3,
//Gets Called if the connection has sucessfully been established
onSuccess: function () {
alert("Connected");
},
//Gets Called if the connection could not be established
onFailure: function (message) {
alert("Connection failed: " + message.errorMessage);
}
};
//Creates a new Messaging.Message Object and sends it to the HiveMQ MQTT Broker
var publish = function (payload, topic, qos) {
//Send your message (also possible to serialize it as JSON or protobuf or just use a string, no limitations)
var message = new Messaging.Message(payload);
message.destinationName = topic;
message.qos = qos;
client.send(message);
}
client.connect(options);
</script>
You can see that I have made changes in ClientId. IBM Watson Iot will accept only the client ids in the below format if you are not using Watson IoT libraries.
var clientId = 'a:OrgId:'+RandomString;
If you are using IBM Watson IoT libraries Client Id can be anything. Even I implemented in node.js

Calling server side function from signalR in Android

SignalR connected in Android, But I want to call a function which is available on server,
I tried the following code,
String host = "Host URL";
HubConnection hubConnection = new HubConnection(host, "", false, new Logger() {
#Override
public void log(String message, LogLevel level) {
System.out.println("message - " + message);
}
});
hubProxy = hubConnection.createHubProxy("Task");
SignalRFuture<Void> signalRFuture = hubConnection.start().done(addSession("Session ID"));
And
private Action<Void> addSession(String sessionID) {
//hubProxy. [server is not available here]
}
In javascript, I tried like following,
$.connection.hub.start().done(function () {
addSession(sessionId)
});
function addSession(sessionId) {
proxy.server.addSession(sessionId)
.done(function () {
isHubConnected = true;
}
);
}
In javascript this works perfectly, But in android :( ,
Update
By trying like #AnikIslamAbhi's answer,
signalRFuture = hubConnection.start().done(addSession("sessionID"));
private Action<Void> addSession(String sessionID) {
System.out.println("addSession : " + sessionID);
hubProxy.invoke("addSession", sessionID);
return null;
}
I received following error message,
InvalidStateException: The operation is not allowed in the 'Connecting' state
In javascript you are using Auto proxy.
But in android you are using manual proxy
Both have differences in their behavior.
Like
To call serverside method using auto proxy
proxy.server.addSession(sessionId)
To call serverside method using manual proxy
proxy.invoke("addSession", sessionId)
You can find more on this link

WebSocket connection established, but can't receive messages

I've written a short WebSocket example server in PHP yesterday. When the client connects to the server, the server reads the client Handshake and sends the server Handshake back with the appropriate key. onopen() of the client gets fired and the server and client seem to be connected.
My problem is: The server can't receive client messages and the client can't receive server messages. onmessage() wasn't triggered once and socket_select() never gives back the client that sent the message on server side.
function connect() {
try {
var webSocketURL = "ws://" + serverAddress + ":" + serverPort;
socket = new WebSocket(webSocketURL);
socket.onopen = function() {
log("Connected! (" + this.readyState + ")");
}
socket.onclose = function() {
log("Closed! (" + this.readyState + ")");
socket.close();
}
socket.onerror = function(error) {
log("Error: " + error.data);
socket.close();
}
socket.onmessage = function(message) {
log("Message from server: " + message.data);
}
}
catch (e) {
alert("Error: " + e);
}
}
The server code is a bit longer, but you can find it here.
Can anyone tell me what's wrong there? Is the handshake incorrect?
Client output:
Connected! (1)
Message to server: 0USERchannel
Server output.
Help is much appreciated, thank you.
On client side, enshure your socket variable is global.

Categories

Resources