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

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.

Related

TypeError: serialport.parsers.readline is not a function

I am trying to run this program in Raspberry Pi 3.
I have installed nodejs and ws on my raspberry pi.
Then I installed serial port module.
I am trying to create this project:enter link description here
I have tried to find solutions everywhere but I could not find one.
If any one knows how to solve this problem please help me.
var webSocketUrl = "wss://api.artik.cloud/v1.1/websocket?ack=true";
var device_id = "5bb3ba9304674086bee67fa507a215cf"; //DEVICE ID
var device_token = "36b278345b6d4d11abf764ae213c5c70"; //DEVICE TOKEN
var WebSocket = require('ws');
var isWebSocketReady = false;
var data="";
var ws = null;
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyACM0", { //for serial communication with arduino
baudrate: 9600,
// The baud rate of uno is 9600
parser: serialport.parsers.readline("\n")
});
/**
* Gets the current time in millis
*/
function getTimeMillis(){
return parseInt(Date.now().toString());
}
/**
* Create a /websocket connection and setup GPIO pin
*/
function start() {
//Create the WebSocket connection
isWebSocketReady = false;
ws = new WebSocket(webSocketUrl);
ws.on('open', function() {
console.log("WebSocket connection is open ....");
register();
});
ws.on('message', function(data) {
//this loop is called whenever the client sends some message
handleRcvMsg(data); //data is send to the function handleRcvMsg()
});
ws.on('close', function() {
console.log("WebSocket connection is closed ....");
});
}
/**
* Sends a register message to /websocket endpoint
*/
//Client will only work when device gets registered from here
function register(){
console.log("Registering device on the WebSocket connection");
try{
var registerMessage = '{"type":"register", "sdid":"'+device_id+'", "Authorization":"bearer '+device_token+'", "cid":"'+getTimeMillis()+'"}';
console.log('Sending register message ' + registerMessage + '\n');
ws.send(registerMessage, {mask: true});
isWebSocketReady = true;
}
catch (e) {
console.error('Failed to register messages. Error in registering message: ' + e.toString());
}
}
//data after receiving is sent here for processing
function handleRcvMsg(msg){
var msgObj = JSON.parse(msg);
if (msgObj.type != "action") return; //Early return;
var actions = msgObj.data.actions;
var actionName = actions[0].name; //assume that there is only one action in actions
console.log("The received action is " + actionName);
}
/**
* Send one message to ARTIK Cloud
*/
//This function is responsible for sending commands to cloud
//function sendStateToArtikCloud(parking,temperature,water){
function sendDataToArtikCloud(pantry){
var result=pantry.split(" ");//data gets split by " " to get the values
try{
ts = ', "ts": '+getTimeMillis();
var data = {
"Garlic": result[1],
"Potato":result[2],
"Temperature":result[3],
"Chilli":result[4],
"Humidity": result[5],
"Ginger":result[6],
"Onion": result[7]
};
var payload = '{"sdid":"'+device_id+'"'+ts+', "data": '+JSON.stringify(data)+', "cid":"'+getTimeMillis()+'"}';
console.log('Sending payload ' + payload + '\n');
ws.send(payload, {mask: true});
} catch (e) {
console.error('Error in sending a message: ' + e.toString() +'\n');
}
}
function exitClosePins() {
console.log('Exit and destroy all pins!');
process.exit();
}
start();
//exectes every second when data is received from arduino (5sec programmed delay from arduino)
sp.on("open", function () {
sp.on('data', function(data) {
console.log("Serial port received data:" + data);
//var result=data.split(" ");//data gets split by " " to get the values
//sendStateToArtikCloud(result[0],result[2],result[1]);//parking,temperature,waterlevel
sendDataToArtikCloud(data);
});
});
process.on('SIGINT', exitClosePins);
I am getting an error on my raspberry pi
enter image description here
Suggest me a solution.
The documentation will tell you that Readline is spelled with a capital R
https://www.npmjs.com/package/serialport#module_serialport--SerialPort.parsers
parser: serialport.parsers.Readline("\n")
~
[TypeError: serialport.parsers.readline is not a function.]
If it has not been resolved yet, try this method.
var serialport = require("serialport")
var SerialPort = serialport.SerialPort;
var sp = new serialport("/dev/ttyACM0"),{
BaudRate: 9600,
parser: new serialport.parsers.Readline("\r\n")
});
I hope your problem is solved.

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

Unsupported URL with post data from IOS to backend service

I want to use webrtc in an IOS (Swift) project. I find so much difficulties to implement it properly. So I searched for an library so I can get how it is implemented to do it later myself.
I found this project:
https://github.com/sushilthe/webrtc-ios-swift
It works fine with https://apprtc.appspot.com. But it is making a POST? request when you want to join a room:
Base url:
https://apprtc.appspot.com/
Part that is appended to the base:
static NSString *kARDRoomServerRegisterFormat =
#"%#/join/%#";
Result:
https://apprtc.appspot.com/join/'roomnr'
I have build a server with some resources from the internet:
$(document).ready(function() { //wait for DOM to be ready for JS execution
easyrtc.setVideoDims(1280, 768);
easyrtc.easyApp('vcdemo', 'self', ['peer'], connectSuccess, failureCallback); //connect to easyrtc app; initiate media sources and elements
});
//global state variables
var myEasyrtcId; //id of client in the signaling framework
//global functions
var connectSuccess = function(easyrtcid) { //join room as defined by "room" parameter in URL
myEasyrtcId = easyrtcid;
console.log('Connect successful. My id is ' + myEasyrtcId + '.');
var room = decodeURIComponent((new RegExp('[?|&]room=' + '([^&;]+?)(&|#|;|$)'). //retrieve room name from URL
exec(location.search) || [, ""])[1].replace(/\+/g, '%20')) || null;
console.log('join room: ' + room);
easyrtc.joinRoom(room, null, joinSuccess, failureCallback);
};
var failureCallback = function(errorCode, errorMsg) { //log error
console.log(errorCode);
console.log(errorMsg);
};
var joinSuccess = function(roomName) { //listen for peers joining the room
setTimeout(function() {
console.log('successfully joined room: ' + roomName);
var peers = easyrtc.getRoomOccupantsAsArray(roomName) || []; //get list of client connected to room
console.log('peers: ' + peers);
var peersLength = peers.length;
if (peersLength > 2) { //support only 1-1 video conferences
alert('The meeting room is already full. ' +
'Only the two peers connecting first will be allowed access.');
} else if(peersLength === 1) { //if no other peer is connected
console.log('waiting for peer to connect...');
} else if(peers[0] != myEasyrtcId) {//get peer id
easyrtc.call(peers[0]);
} else {
easyrtc.call(peers[1]);
}
}, 100);
};
This works perfect in chrome and firefox via this url:
localhost:8080/?room=123
And I can connect to that stream when I reuse that room number. Perfect!
So I thought I can implement that in the app, I have changed the serverHostUrl to: client?.serverHostUrl = "192.168.1.59:8080"
And the other variable:
static NSString *kARDRoomServerRegisterFormat = #"%#/?room=%#";
But I get an error when it try's to submit the url:
Client Connecting
2016-10-17 19:24:51.151795 WebRTC iOS Swift[3944:1036130] Registering with room server.
2016-10-17 19:24:51.151900 WebRTC iOS Swift[3944:1036130] url = 192.168.1.59:8080/?room=123
2016-10-17 19:24:51.207496 WebRTC iOS Swift[3944:1036130] Error posting data: unsupported URL
Client Disconnected
I have searched a few hours why this is happening. But I can't find the problem. Thank you very much!
EDIT
The Code where it goes wrong:
The roomURL is: 192.168.1.59:8080/?room=123 at that moment.
[NSURLConnection sendAsyncPostToURL:roomURL
withData:nil
completionHandler:^(BOOL succeeded, NSData *data) {
ARDAppClient *strongSelf = weakSelf;
if (!succeeded) {
NSError *error = [self roomServerNetworkError];
[strongSelf.delegate appClient:strongSelf didError:error];
completionHandler(nil);
return;
}
ARDRegisterResponse *response =
[ARDRegisterResponse responseFromJSONData:data];
completionHandler(response);
}];

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

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.

Working Hello World WebRTC DataChannel Examples with Signaling Implemented

The intent is for this to become a Community Wiki post that is kept up-to-date so developers interested in implementing communication of JSON messages browser-to-browser (p2p) with WebRTC DataChannels have simple yet functional examples.
WebRTC DataChannels are experimental and still in draft. It seems that currently the web is a minefield of outdated WebRTC examples and even more so if a developer is trying to learn the RTCDataChannel API.
Simple yet functional 1-page examples that work today across WebRTC compliant browsers seem very difficult to find. For example, some examples leave out a signaling implementation, others only work for a single browser (e.g. Chrome-Chrome), many are outdated due to recent API changes, and others are so complex they create a barrier to getting started.
Please post examples that meet the following criteria (if something is not met please specify):
Client-side code is 1-page (200 lines or less)
Server-side code is 1-page and technology is referenced (e.g. node.js, php, python, etc.)
Signaling mechanism is implemented and protocol technology is referenced (e.g. WebSockets, long polling, GCM, etc.)
Working code that runs cross-browser (Chrome, Firefox, Opera, and/or Bowser)
Minimal options, error handling, abstraction, etc. -- the intent is an elementary example
Here is a working example that uses HTML5 WebSockets for signaling and a node.js backend
signaling technology: WebSockets
client: pure html/javascript
server: node.js, ws
last tested on: Firefox 40.0.2, Chrome 44.0.2403.157 m, Opera 31.0.1889.174
client-side code:
<html>
<head>
</head>
<body>
<p id='msg'>Click the following in different browser windows</p>
<button type='button' onclick='init(false)'>I AM Answerer Peer (click first)</button>
<button type='button' onclick='init(true)'>I AM Offerer Peer</button>
<script>
(function() {
var offererId = 'Gandalf', // note: client id conflicts can happen
answererId = 'Saruman', // no websocket cleanup code exists
ourId, peerId,
RTC_IS_MOZILLA = !!window.mozRTCPeerConnection,
RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection || window.msRTCPeerConnection,
RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.msRTCSessionDescription,
RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.msRTCIceCandidate,
rtcpeerconn = new RTCPeerConnection(
{iceServers: [{ 'url': 'stun:stun.services.mozilla.com'}, {'url': 'stun:stun.l.google.com:19302'}]},
{optional: [{RtpDataChannels: false}]}
),
rtcdatachannel,
websocket = new WebSocket('ws://' + window.location.hostname + ':8000'),
comready, onerror;
window.init = function(weAreOfferer) {
ourId = weAreOfferer ? offererId : answererId;
peerId = weAreOfferer ? answererId : offererId;
websocket.send(JSON.stringify({
inst: 'init',
id: ourId
}));
if(weAreOfferer) {
rtcdatachannel = rtcpeerconn.createDataChannel(offererId+answererId);
rtcdatachannel.onopen = comready;
rtcdatachannel.onerror = onerror;
rtcpeerconn.createOffer(function(offer) {
rtcpeerconn.setLocalDescription(offer, function() {
var output = offer.toJSON();
if(typeof output === 'string') output = JSON.parse(output); // normalize: RTCSessionDescription.toJSON returns a json str in FF, but json obj in Chrome
websocket.send(JSON.stringify({
inst: 'send',
peerId: peerId,
message: output
}));
}, onerror);
}, onerror);
}
};
rtcpeerconn.ondatachannel = function(event) {
rtcdatachannel = event.channel;
rtcdatachannel.onopen = comready;
rtcdatachannel.onerror = onerror;
};
websocket.onmessage = function(input) {
var message = JSON.parse(input.data);
if(message.type && message.type === 'offer') {
var offer = new RTCSessionDescription(message);
rtcpeerconn.setRemoteDescription(offer, function() {
rtcpeerconn.createAnswer(function(answer) {
rtcpeerconn.setLocalDescription(answer, function() {
var output = answer.toJSON();
if(typeof output === 'string') output = JSON.parse(output); // normalize: RTCSessionDescription.toJSON returns a json str in FF, but json obj in Chrome
websocket.send(JSON.stringify({
inst: 'send',
peerId: peerId,
message: output
}));
}, onerror);
}, onerror);
}, onerror);
} else if(message.type && message.type === 'answer') {
var answer = new RTCSessionDescription(message);
rtcpeerconn.setRemoteDescription(answer, function() {/* handler required but we have nothing to do */}, onerror);
} else if(rtcpeerconn.remoteDescription) {
// ignore ice candidates until remote description is set
rtcpeerconn.addIceCandidate(new RTCIceCandidate(message.candidate));
}
};
rtcpeerconn.onicecandidate = function (event) {
if (!event || !event.candidate) return;
websocket.send(JSON.stringify({
inst: 'send',
peerId: peerId,
message: {candidate: event.candidate}
}));
};
/** called when RTC signaling is complete and RTCDataChannel is ready */
comready = function() {
rtcdatachannel.send('hello world!');
rtcdatachannel.onmessage = function(event) {
document.getElementById('msg').innerHTML = 'RTCDataChannel peer ' + peerId + ' says: ' + event.data;
}
};
/** global error function */
onerror = websocket.onerror = function(e) {
console.log('====== WEBRTC ERROR ======', arguments);
document.getElementById('msg').innerHTML = '====== WEBRTC ERROR ======<br>' + e;
throw new Error(e);
};
})();
</script>
</body>
</html>
server-side code:
var server = require('http').createServer(),
express = require('express'),
app = express(),
WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ server: server, port: 8000 });
app.use(express.static(__dirname + '/static')); // client code goes in static directory
var clientMap = {};
wss.on('connection', function (ws) {
ws.on('message', function (inputStr) {
var input = JSON.parse(inputStr);
if(input.inst == 'init') {
clientMap[input.id] = ws;
} else if(input.inst == 'send') {
clientMap[input.peerId].send(JSON.stringify(input.message));
}
});
});
server.on('request', app);
server.listen(80, YOUR_HOSTNAME_OR_IP_HERE, function () { console.log('Listening on ' + server.address().port) });

Categories

Resources