socket.io to talk to server that is implementing RFC6455 in a strict fashion - websocket

I am trying to make my socket.io javascript client talk to a server implemented in cpp using websocketpp and its not working. Its surprising that I cant configure socket.io to fall back to real websockets when I need them.
Any one has any ideas or suggestions on this ? going back to websocket npm and re implementing my client is the only way ?
I tried this, but it does not work
var socket = io.connect('http://localhost:8080', {
transports: [
'websocket',
'polling'
]
});

socket.io is an additional protocol on top of webSocket so a socket.io client can ONLY talk to a socket.io server. While socket.io uses webSocket for the transport, it needs support for it's additional layer on top of webSocket to work properly.
If you want to talk to a plain webSocket server, then you should use a plain webSocket client.
var socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server', event.data);
});
You can probably find a socket.io server modules for cpp if you'd like to fix the server-side of things to talk socket.io.

Related

Connecting to AWS IoT Websocket without MQTT client

I have a client application which runs in the browser which I can't change the implementation of to implement an MQTT client such as mqtt on npm.
The code in the library is as follows and allows me to pass in a socketUrl
const ws = new WebSocket(socketUrl)
I have tried generating a presigned URL for IoT, which seems to work in terms of authenticating (i.e. no Unauthorized response) but I get a 426 Upgrade Required response.
I believe I'm correct in saying that if it were working it'd reply with a 101 Switching protocols but without knowing much about MQTT i'm unsure if this is not happening because I'm doing something wrong or because I'm not using MQTT.
I'm generating a signed URL using the below code (I'll switch to Cognito Identities if I get this working rather than using the fixed key/secret)
const v4 = require('aws-signature-v4')
const crypto = require('crypto')
const socketUrl = v4.createPresignedURL(
'GET',
'myioturl.iot.us-east-1.amazonaws.com',
'/mqtt', // tried just /mytopic, too
'iotdevicegateway',
crypto.createHash('sha256').update('', 'utf8').digest('hex'), {
'key': 'removed',
'secret': 'removed',
'protocol': 'wss',
'region': 'us-east-1'
}
)
The protocols page in the iot documentation seems to suggest that if I point at /mqtt I'm indicating I'll be using MQTT.
mqtt Specifies you will be sending MQTT messages over the WebSocket protocol.
What does this mean if I just specify /foobar? Should I be able to connect to the socket but not using MQTT?
There are quite a few unknowns for me so I'm struggling to work out if it should work at all, and if so, which bit am I doing wrong.

Websockets in Suave

I've been looking into using websockets with the Suave web server. Unfortunately, it's not very well documented, and all I've managed to find was this: https://github.com/SuaveIO/suave/tree/master/examples/WebSocket
However, that only shows the websocket responding to the client that made the request, and I want to basically have the socket respond to all connected clients. Something like a chat server.
I've used SignalR in the past, but would prefer to avoid it for this.
So, how would I go about having the Suave server send data to all connected websocket clients?
Suave doesn't provide anything like that out of the box, however you can easily extend the example to do so.
The socket handler ws passed to the handShake function can pass the client information outside, and you can build a send/broadcast API around it.
The ws function can be modified for example like this
let ws onConnect onDisconnect (webSocket: WebSocket) (context: HttpContext) =
let loop () = (* the socket logic stays the same *)
socket {
onConnect webSocket context
try
do! loop ()
finally
onDisconnect context
}
Then it's up to you to inject the onConnect and onDisconnect handles to register/unregister clients.
I use a MailboxProcessor to serialize the Connect/Disconnect/Send operations, alternatively it's easy to use Reactive Extensions, or a shared mutable concurrent storage like ConcurrentDictionary...

How to configure my sails app with https socket connection?

I have a sails backend API. And I already have an https connection.
(https://myapp.com/api)
How do I connect to a sails socket with my client side (Android and iOS) having an https connection? I dont have any problem connecting to a non HTTPS server. Hope there is a help.
all you have to do is open config/bootstrap.js, and made following changes there
module.exports.bootstrap = function(cb) {
// handle connect socket first event executes after logged in
sails.io.on('connect', function (socket){
socket.emit("connected",{ data: "here am i!" })
});
// handle custom listener for other stuff
sails.io.on('ping', function (socket){
socket.emit("pong",{ data: "send to android/ios/web client" })
});
cb();
};
here you can listen for multiple events as well as you can emit multiple private/broadcast messages as well and also all socket.io listeners will work here

Dart, how to listen for websocket close on server side?

I see that client side websockets have an onlClose stream which is useful, but why isn't there a complimentary onclose stream on the server side websocket? I would like to be able to clean up my websessions on the server side when the web socket closes but Im not sure how to detect that event occuring on the server side.
The server-side WebSocket API is a Stream. That means that to listen on data, you can do the following:
websocket.listen((data) {
// Do something with data.
}, onDone: () {
// No more data - read-direction was closed.
});
Where the onDone callback is invoked, when the WebSocket is closed.

socket.io switch to ajax from client side

Is it possible to change preffered io.transports from client side? For some reasons some clients cant use websockets, so I want to make button which changes prefferef transports list. How should I do this?
Socket.io client automatically determines the available transports and there is an option of try multiple transports which is true by default and it tries all available transports before finally giving up. You should enable all the transports on server side like this:
io.set('transports', [
'websocket'
,'flashsocket'
,'htmlfile'
,'xhr-polling'
,'jsonp-polling'
]);
However you can enable a transport on client side as:
socket = io.connect(HOSTNAME, {
transports: ['xhr-polling']
});

Resources