How to know my socket connect is success or not? - sockets

I want to do something when the nodejs server is started or I will do something else not related to the server.
But how could I know that. There is no property that shows the status of the connection, and because the socket is asynchronous that I can't get the err by try..catch...
The following is my clinet code.
var socket = io.connect('http://localhost:3000/monitor');
socket.on('message', function (data) {
console.log(data);
});
Anyone can tell me how to if(is connected).. else.. in this place?

Try listening to the following events:
socket.on( 'connect', function() {
});
socket.on( 'disconnect', function() {
});
socket.on( 'connect_failed', function() {
});
socket.on( 'error', function() {
});
Socket.io has some bugs in firing some events so it's better to listen to all of those that might mean a connection failed.

Related

How do i use sockets in sailsjs version 1.4

I am trying to use sockets in sailsjs.
I have an action which just returns the socketId
module.exports = async function exampleAction(req, res) {
if (!req.isSocket) {
console.log("not a socket req");
return res.badRequest();
}
sails.sockets.getId(req);
return res.json({ socketid: sails.sockets.getId(req) });
};
and in routes.js:
"GET /label/exampleaction": {
action: "label/example-action",
isSocket: true,
},
I'm trying to connect to it from nuxt.js using Websocket :
this.connection = new WebSocket("ws://localhost:1337/label/exampleaction");
This gives me an error:
WebSocket connection to 'ws://localhost:1337/label/exampleaction' failed:
What am I doing wrong?
First of all, try to make this controller simpler, only for tests.
Like this:
async function onConnect(req, res) {
const socketId = sails.sockets.getId(req);
res.json(socketId);
}
'POST /connect': { controller: 'TestController', action:'onConnect' },
For client part, i recommend use the sails browser library: https://github.com/balderdashy/sails.io.js
You can use it in your nuxt app, it is all javascript, no mistery.
Sails Docs have a specific section with more details: https://sailsjs.com/documentation/reference/web-sockets/socket-client

socket.io-client Jest testing inconsistent results

I am writing some end-to-end test cases to test socket connections in my app. I expect receiving socket events after specific rest API requests. For instance, after hitting: /api/v1/[createTag], I expect receiving createTag event to be captured by socket.io-client. The issue is that, it is very inconsistently passing, and sometimes failing, with good rest API requests. The reason to fail is that done() event inside socket.on('createTag' ... is never called, so it gets timeout. On browser, currently all the API endpoints and sockets seem to be working fine. Is there a specific configuration that I might be missing in order to test socket.io-client within Node.js environment and Jest?
Below is my test cases, and thanks a lot in advance:
describe('Socket integration tests: ', () => {
beforeAll(async done => {
await apiInit();
const result = await requests.userSignIn(TEST_MAIL, TEST_PASSWORD);
TEST_USER = result.user;
SESSION = result.user.session;
console.log('Test user authenticated succesfully.');
done();
});
beforeEach(done => {
socket = io(config.socket_host, { forceNew: true })
socket.on('connect', () => {
console.log('Socket connection succesful.');
socket.emit('session', { data: SESSION }, (r) => {
console.log('Socket session successful.');
done();
});
});
})
test('Receiving createTag socket event?', async(done) => {
console.log('API request on createTag');
const response = await Requester.post(...);
console.log('API response on createTag', response);
socket.on('createTag', result => {
console.log('createTag socket event succesful.');
createdTagXid = result.data.xid;
done();
})
});
afterEach(done => {
if(socket.connected) {
console.log('disconnecting.');
socket.disconnect();
} else {
console.log('no connection to break');
}
done();
})
}
Basically, setting event handles after async API calls seems to be the issue. So I should have first set the socket.on( ... and then call rest API.

Socket working only with debug mode react native

My socket emit works properly only on debug mode, when i tried with release APK nothing happened.
Code to connect socket -
socket = io(SOCKET_URL, {
transports: ['websocket'],// you need to explicitly tell it to use websockets
forceNew: true,
jsonp: false
});
socket.on('connect', () => {
console.log('connected!');
});
socket.on('disconnect', () => {
console.log('disconnect!');
});
Code to emit event
socket.emit('LIVE_MSG', { msg: "asdfasasdf3" }, (res) => {
console.log(res);
})
I have tried many options with socket connection i.e. timeout, setting and removing jsonp
Also tried with window.navigator.userAgent = "react-native";
But the result is none, socket only emits event when it is in debug mode, gone mad why it is not working with release apk.
Please help.
If you don't specify url, socket set url as localhost.
https://socket.io/get-started/chat/
"Notice that I’m not specifying any URL when I call io(), since it defaults to trying to connect to the host that serves the page."
(I'm not familiar with socet.io.)

Getting and "Error, wrong validation token" when trying to create a Facebook Chatbot

I'm trying to create a Facebook chatbot with NodeJS, Express, and a Heroku server.
I created my webhook on heroku and had it verified and saved by facebook. I then started adding code that would reply to the incoming messages and I can't seem to get it connected. It keeps saying "Error, wrong validation token" when I try to load my webhook in my browser. And when I try to send my bot a message I get no response. Even though I already had it verified and didn't change the code.
Here is my code:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var port = process.env.PORT || 3000;
// body parser middleware
app.use(bodyParser.urlencoded({ extended: true }));
// test route
//app.get('/', function (req, res) { res.status(200).send('Hello world!') });
app.get('/', function (req, res) {
if (req.query['hub.verify_token'] === '8FKU9XWeSjnZN4ae') {
res.send(req.query['hub.challenge']);
}
res.send('Error, wrong validation token');
})
app.post('/', function (req, res) {
messaging_events = req.body.entry[0].messaging;
for (i = 0; i < messaging_events.length; i++) {
event = req.body.entry[0].messaging[i];
sender = event.sender.id;
if (event.message && event.message.text) {
text = event.message.text;
sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
}
}
res.sendStatus(200);
});
// error handler
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(400).send(err.message);
});
app.listen(port, function () {
console.log('Listening on port ' + port);
});
var token = <myToken>;
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
}
So I'm confused as to why nothing is happening and why I'm getting that error. I feel like I'm missing a whole step. I am following this tutorial by the way: https://developers.facebook.com/docs/messenger-platform/quickstart
Any help is appreciated. Thanks!
Edit: Here are my heroku logs
Do not post your full access tokens here!
Have you tested the output of the challenge? Since it's just a GET and you know all values you can try it yourself: your-app-domain.com/your-callback-url?hub_mode=subscribe&hub_verify_token=the_token_you_set_in_your_app_config&hub_challenge=ping which sould print 'ping' if everything work fine.
Make sure you add sendStatus(200) to the hub challenge response, too.
You need to subscribe your page to the app first. To do so make a POST request to /your-page-id/subscribed_apps which should return "success". You can make a GET request to the same endpoint afterwards to double check your app is subscribed to your page
You did not mention which events you subscribed to (needs to be message_deliveries, messages, messaging_optins, messaging_postbacks)
Make sure the webhooks tab in your app dashboard now says "complete"
Test again
You are actually using "request" but you are never importing it anywhere. Here's how to fix it:
var request = require("request")
Once you have added that to your index.js or app.js file (basically whatever this file is), make sure you do:
npm install request --save
This should fix it. Unfortunately, Heroku doesn't error out and say that it does not know what "request" is and that's why it was so hard to figure this out in the first place!

Node.js TCP client behaving differently from Netcat/Telnet

I am issuing newline-separated text commands to a custom protocol TCP server. In the example below I issue 2 commands and receive a response written back. It works as expected in telnet and netcat:
$ nc localhost 1234
command1
command2
theresponse
The same workflow is not working when connecting with Node.js:
var net = require('net');
var client = net.connect(1234, 'localhost');
client.on('data', function(data) {
console.log('data:', data.toString());
});
client.on('error', function(err) {
console.log('error:', err.message);
});
client.write('command1\n');
client.write('command2\n');
I would expect that after running this program I would see "data: theresponse" written to the console, however, nothing is ever printed. I have also tried performing the writes inside of the "connect" callback, but I have the same results. The curious thing is that when I try this in the Node REPL...it works:
$ node
> var net = require('net')
undefined
> var client = net.connect(1234, 'localhost')
undefined
> client.on('data', function(data) { console.log('data:', data.toString()); })
{ ... }
> client.write('command1\n')
true
> client.write('command2\n')
true
> data: theresponse
Anyone have ideas about this bizarre behavior?
Thanks.
-Scott
Without testing the code, I'm presuming it's the asynchronous nature of Node.js that's biting you. In the REPL the connection happens before you can type in another command. In your code above you are writing before you are connecting.
Change the above code to this:
var net = require('net');
var client = net.connect(1234, function(){
client.on('data', function(data) {
console.log('data:', data.toString());
});
client.on('error', function(err) {
console.log('error:', err.message);
});
client.write('command1\n');
client.write('command2\n');
});