How to redirect messages from one endpoint to another using java websockets (jsr 356) - endpoint

I am doing a personal project to learn about java websockets. Basically my HTML clients sends messages to my server through JSR 356 websockets. The endpoint #ServerEndpoint("/wsServer") receives all messages from the clients and I would like to see those messages in another portal/endpoint #ServerEndpoint("/wsDashboard") as a dashboard in real time.
I would appreciate any idea, documentation or piece of code to start with as I really have no idea, I have seen solutions like apache kafka, but I am not sure if this is what I need.
thanks

Create Java Web Socket Client for /wsDashboard on onmessage method of a #ServerEndpoint("/wsServer") end point and keep it in user properties. wher you receive a message just forward the message to /wsServer web socket.
#ServerEndpoint("/wsServer")
public class MyWSServerEndPoint{
#OnOpen
public void open( Session session) {
// Open java client websocket connection to /wsDashboard and keep the object in
session.getUserProperties().put("wsDashboard ", websocket);
}
#OnMessage
public void onMessage(String message,Session session){
//forwarding the message
session.getUserProperties().get("wsDashboard ").getRemote().send(message);
}
#OnClose
public void onClose(Session session){
session.getUserProperties().get("wsDashboard ").close();
}
}
To create a client end point here is good example
http://www.hascode.com/2014/11/creating-different-websocket-chat-clients-in-java/

Related

Is it possible to connect to the Google IOTCore MQTT Bridge via Javascript?

I've been trying to use the javacscript version of the Eclipse Paho MQTT client to access the Google IOTCore MQTT Bridge, as suggested here:
https://cloud.google.com/iot/docs/how-tos/mqtt-bridge
However, whatever I do, any attempt to connect with known good credentials (working with other clients) results in this connection error:
errorCode: 7, errorMessage: "AMQJS0007E Socket error:undefined."
Not much to go on there, so I'm wondering if anyone has ever been successful connecting to the MQTT Bridge via Javascript with Eclipse Paho, the client implementation suggested by Google in their documentation.
I've gone through their troubleshooting steps, and things seem to be on the up and up, so no help there either.
https://cloud.google.com/iot/docs/troubleshooting
I have noticed that in their docs they have sample code for Java/Python, etc, but not Javascript, so I'm wondering if it's simply not supported and their documentation just fails to mention as such.
I've simplified my code to just use the 'Hello World' example in the Paho documentation, and as far as I can tell I've done things correctly (including using my device path as the ClientID, the JWT token as the password, specifying an 'unused' userName field and explicitly requiring MQTT v3.1.1).
In the meantime I'm falling back to polling via their HTTP bridge, but that has obvious latency and network traffic shortcomings.
// Create a client instance
client = new Paho.MQTT.Client("mqtt.googleapis.com", Number(8883), "projects/[my-project-id]/locations/us-central1/registries/[my registry name]/devices/[my device id]");
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect the client
client.connect({
mqttVersion: 4, // maps to MQTT V3.1.1, required by IOTCore
onSuccess:onConnect,
onFailure: onFailure,
userName: 'unused', // suggested by Google for this field
password: '[My Confirmed Working JWT Token]' // working JWT token
function onFailure(resp) {
console.log(resp);
}
// called when the client connects
function onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("onConnect");
client.subscribe("World");
message = new Paho.MQTT.Message("Hello");
message.destinationName = "World";
client.send(message);
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
// called when a message arrives
function onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
}
I'm a Googler (but I don't work in Cloud IoT).
Your code looks good to me and it should work. I will try it for myself this evening or tomorrow and report back to you.
I've spent the past day working on a Golang version of the samples published on Google's documentation. Like you, I was disappointed to not see all Google's regular languages covered by samples.
Are you running the code from a browser or is it running on Node.JS?
Do you have a package.json (if Node) that you would share too please?
Update
Here's a Node.JS (JavaScript but non-browser) that connects to Cloud IoT, subscribes to /devices/${DEVICE}/config and publishes to /devices/${DEVICE}/events.
https://gist.github.com/DazWilkin/65ad8890d5f58eae9612632d594af2de
Place all the files in the same directory
Replace values in index.js of the location of Google's CA and your key
Replaces [[YOUR-X]] values in config.json
Use "npm install" to pull the packages
Use node index.js
You should be able to pull messages from the Pub/Sub subscription and you should be able to send config messages to the device.
Short answer is no. Google Cloud IoT Core doesn't support WebSockets.
All the JavaScript MQTT libraries use WebSocket because JavaScript is restricted to perform HTTP requests and WebSocket connections only.

Jetty http/2 add ServerSessionListener to server

i am using embedded Jetty to implement HTTP/2. At the moment i am trying to add a ServerSessionListener (from: org.eclipse.jetty.http2.api.Session.Listener.Adapter) to my Server.
i tried to add it to the Context and Server via: addEventListener with no success.
Maybe someone can give me a hint about what i am doing wrong..
I want to add a session Listener to my HTTP2 Connection to track the connected Sessions (Clients) and their connection duration.
Regards!
You can add an implementation of Connection.Listener as a bean to the connector itself, for example:
http2Connector.addBean(new Connection.Listener()
{
public void onOpened(Connection connection) { ... }
public void onClosed(Connection connection) { ... }
});
Alternatively you can add the Connection.Listener as a bean to the ConnectionFactory.
In both cases, every time a connection is created, the listener is added to the connection and will be invoked when the connection opens and when it closes.
You can use Jetty's ConnectorStatistics class that already gathers a number of statistics about connections and already implements Connection.Listener.

C++, Mongoose: How to make a POST request?

I'm working on a project that uses Mongoose, and I need to make a POST request to another server. I don't see an example of how to do this in their examples list, does anyone know how to do this?
EDIT to add more detail:
I'm working within a larger C++ app and need to create a simple server such that a user can query the app for information. Right now, I start the server like this:
Status sampleCmd::startServer()
{
Status stat = MS::kSuccess;
struct mg_server *server;
// Create and configure the server
server = mg_create_server(NULL, ev_handler);
mg_set_option(server, "listening_port", "8080");
stopServer = false;
printf("Starting on port %s\n", mg_get_option(server, "listening_port"));
while (!stopServer) //for (;;)
{
mg_poll_server(server, 1000);
}
// Cleanup, and free server instance
mg_destroy_server(&server);
return stat;
}
In my event handler, I parse the provided URI for a particular one and then run some commands with the application's API. I need to send these results back to a server for the user to see. It's this latter step that is unclear to me. It seems odd that a web server library wouldn't have some client functionality, don't servers need to talk to other servers?
Okay, it turns out I was thinking about this wrong. I needed to respond to the POST request I was getting. So using mg_printf_data(...) with the connection object worked for me.

Use ColdFusion to read events over a TCP/IP stream

Our new phone system is making use of Asterisk manager API which allows to read events and issue commands over a TCP/IP stream. My question is.. Is there any way at all to use ColdFusion to read (and in-turn process) the stream of events? As of now I'm able to view the phone events (incoming calls, transfers, hang-ups etc) via telnet and I'm wondering if it's possible to use a ColdFusion event gateway to process these events as they come over?
Once the initial connection is made (via telnet), I have to submit the following key:values in order to authenticate the connection before the stream begins.
Action: login<CRLF>
Username: usr<CRLF>
Secret: abc123<CRLF>
<CRLF>
Just wanted to specify that as I'm not sure if that's a deal-breaker with possibly using a web service in this manner. Also note we are using ColdFusion 10 Enterprise.
I realize this is an old thread, but I am posting this in case it helps the next guy ....
AFAIK, it cannot be done with a standard CF Event Gateway. However, one possibility is using Asterisk-Java. It is a java library that allows communication with an Asterisk Server. More specifically it Manager interface:
... is capable of sending [actions] and receiving [responses] and
[events]. It does not add any further functionality but rather
provides a Java view to Asterisk's Manager API (freeing you from
TCP/IP connection and parsing stuff).
So it can be used to issue commands to the server, and receive events, just like telnet.
Starter example:
Download the Asterisk-Java jar and load it via this.javaSettings in your Application.cfc
Create a ManagerConnection with the settings for your Asterisk server
factory = createObject("java", "org.asteriskjava.manager.ManagerConnectionFactory");
connection = factory.init( "hostNameOrIP"
, portNum
, "userName"
, "theSecret" ).createManagerConnection();
Create a CFC to act as a listener. It will receive and handle events from Asterisk:
component {
public void function onManagerEvent(any managerEvent)
{
// For demo purposes, just output a summary of the event
WriteLog( text=arguments.managerEvent.toString(), file="AsteriskLog" );
}
}
Using a bit of dynamic proxy magic, register the CFC with the connection:
proxyListener = createDynamicProxy("path.YourCFCListener"
, ["org.asteriskjava.manager.ManagerEventListener"]);
connection.addEventListener( proxyListener );
Login to the server to begin receiving events. Setting the appropriate event level: "off", "on" or csv list of available events - "system", "call" and/or "log".
connection.login("on");
Run a simple "Ping" test to verify everything is working. Then sleep for a few seconds to allow some events to flow. Then close the connection.
action = createObject("java", "org.asteriskjava.manager.action.PingAction").init();
response = application.connection.sendAction(action);
writeDump(response.getResponse());
// disconnect and stop events
sleep(4000);
connection.logoff();
Check the demo log file. It should contain one or more events.
"Information","http-bio-8500-exec-4","10/14/16","15:17:19","XXXXX","org.asteriskjava.manager.event.ConnectEvent[dateReceived=Fri Oct 14 15:17:19 CDT 2016,....]"
NB: In a real application, the connection would probably be opened once, in OnApplicationStart, and stored in a persistent scope.
Events would continue to stream as long as the connection remained open. The connection should only be closed when the application
ends, to halt event streaming.
Yes-- you'd want to use a Socket Gateway. Ben Nadel has a great writeup about how to do this: Using Socket Gateways To Communicate Between ColdFusion And Node.js
Although he uses Node.js in his example, you should be able to use his guide to set up the Socket Gateway, then handle the data passed to it as you see fit.
What you want is a server-side TCP client. I suggest easySocket, a simple UDF that allows you to send TCP messages via Coldfusion by utilizing Java sockets.

How do I set timeout for TIdHTTPProxyServer (not connection timout)

I am using TIdHTTPProxyServer and now I want to terminate connection when it is success to connect to the target HTTP server but receive no response for a long time(i.g. 3 mins)
Currently I find no related property or event about it. And even if the client terminate the connection before the proxy server receive the response from the HTTP server. OnException Event will not be fired until the proxy server receive the response. (That is, if the proxy server still receive no response from HTTP Server, I even do not know the client has already terminate the connection...)
Any help will be appreciated.
Thanks!
Willy
Indy uses infinite timeouts by default. To do what you are asking for, you need to set the ReadTimeout property of the outbound connection to the target server. You can access that connection via the TIdHTTPProxyServerContext.OutboundClient property. Use the OnHTTPBeforeCommand event, which is triggered just before the OutboundClient connects to the target server, eg:
#include "IdTCPClient.hpp"
void __fastcall TForm1::IdHTTPProxyServer1HTTPBeforeCommand(TIdHTTPProxyServerContext *AContext)
{
static_cast<TIdTCPClient*>(AContext->OutboundClient)->ReadTimeout = ...;
}