SailsJs websocket with a custom route instead of blueprint? - javascript

I am following the official Sails docs. Would like to implement the most basic socket functionality, i.e. client connects to a socket and when server notifies it about a response, executes a script.
The problem is that the socket requests are http and I am getting badRequest.
What's the right way to register a socket route in Sails?
My client code:
io.socket.on('hello', function (data) {
console.log('Socket `' + data.id + '` joined the party!')
})
io.socket.get('/sayhello', function gotResponse(data, jwRes) {
console.log('Server responded with status code ' + jwRes.statusCode + ' and data: ', data);
});
The controller:
module.exports = {
exits: {
badRequest: {
responseType: 'badRequest',
description: 'The provided data is invalid.',
},
},
fn: async function (req, res) {
if (!req.isSocket) {
return res.badRequest();
}
sails.sockets.join(req, 'funSockets');
sails.sockets.broadcast('funSockets', 'hello', {howdy: 'hi there!'}, req);
return res.json({
anyData: 'we want to send back'
});
}
}
The route:
'GET /sayhello': { action: 'project/api/app-socket' },

In your routes.js file you have:
'GET /sayhello': { action: 'project/api/app-socket' },
Add to this isSocket: true. So make it:
'GET /sayhello': { action: 'project/api/app-socket', isSocket: true },
How I learned this?
The convention for subscribe endpoints is to use an action prefixed with "subscribe", so when I generated an action with this command and this prefix:
sails generate action task/subscribe-to-task
Then it gave me this hint in the terminal output:
Successfully generated:
•- api/controllers/task/subscribe-to-task.js
A few reminders:
(1) For most projects, you'll need to manually configure an explicit route
in your `config/routes.js` file; e.g.
'GET /api/v1/task/subscribe-to-task': { action: 'task/subscribe-to-task', isSocket: true },
That's how I learned that we needed to add isSocket: true.

Related

Braintree Node.js cannot get transaction.sale to work

I am building a reactjs app that among others will include Braintree Dropin UI integration. So far, I have managed to make the UI show up and send a payload to the back end. However, I cannot get the gateway.transaction.sale() part to work. Here is my code's relevant parts:
When the user clicks the pay button, this is fired:
instance.requestPaymentMethod().then(function (payload) {
console.log(payload);
completePayment(amount, payload.nonce, userId, sessionId).then((result) => {
console.log( result );
});
}).catch(function (err) {
alert(err.message);
});
And this is the code that should handle the transaction:
return gateway.transaction.sale({
amount: amount,
paymentMethodNonce: nonce,
customFields: {
session_id: sessionId,
user_id: userId
},
options: {
submitForSettlement: true
}
}).then(function (result) {
if (result.success) {
console.log('Transaction ID: ' + result.transaction.id);
} else {
console.error(result.message);
}
}).catch(( error ) => {
alert(error);
});
Every time this function is fired, I get this error from catch:
TypeError: can't assign to property "success" on :not an object
Can anyone point me in the right direction?
Please note that I am not very familiar with react, node etc so my code may not be the best thing around...
Check these points:
make sure you assigned your environment to the sandbox (braintree.Environment.Sandbox);
double check (merchantId, publicKey, and privateKey).

socket.emit only emitting to emitter

I am using react-native with socket.io to send and receive contact requests but my code is only emitting to the emitter and to no one else.
This is the server side:
users = []; // Each time a new user joins the server they are saved in this array
socket.on('create connection', function(data, callback) {
if(data.receiverId in users) { // If the user you want to add is online then callback is true else callback is false
// The underneath line is the one that I will be using but nothing happend
//io.sockets.in(data.receiverId).emit('save room', data);
// So I created this one to see if I actually was emitting something
socket.emit('save room', data); // I found out that the emitting was working but only with the emitter
callback(true);
}else
callback(false);
});
So my conclusion is that my server side is correct and the problem lies on my client side
This is my client side:
constructor() {
this.socket = SocketIOClient('http://192.168.15.4:8000');
this.socket.on('save room', function (data) { // This is where the server calls the emit. It was at first inside the connect function but I moved it to the constructor to see if that way all clients could get it, results are the same
Alert.alert(
'Accept Connection?',
'User: '+data.emitterId+' sent you a connection request',
[
{
text: 'Accept',
onPress: () => {},
},
{
text: 'Refuse',
onPress: () => {},
},
],
{cancellable: false}
);
})
}
#action connect(data, callback1) { // this access the function we had previously in the server
this.socket.emit('create connection', data, function (callback2) {
if(!callback2)
Alert.alert(
'User Offline',
'This user is currently offline try again later',
[
{
text: 'OK',
onPress: () => {callback1(false)},
},
],
{cancellable: false}
);
else {
callback1(true)
}
});
}
I think the problem lies on where I place the this.socket.on('save room') function, but in react-native I really do not know where to put it.
Thanks to #H. Tugkan kibar and #azium I realized that the problem was on my server side the correct way to emit to a specific user is like this:
socket.broadcast.to().emit();

Expecting a token named "token

I can't figure out what's causing this error with https://github.com/sahat/satellizer
satellize.js configurations
withCredentials: !1,
tokenRoot: null,
cordova: !1,
baseUrl: "/#",
loginUrl: "/auth/login",
signupUrl: "/auth/signup",
unlinkUrl: "/auth/unlink/",
tokenName: 'token',
tokenPrefix: "satellizer",
authHeader: "Authorization",
authToken: "Bearer",
storageType: "localStorage",
app.js
.config(function($authProvider) {
$authProvider.facebook({
clientId: '******'
});
$authProvider.google({
clientId: '****'
});
})
controller
$scope.socialLogin = function(provider) {
$auth.authenticate(provider)
.then(function(data) {
toastr.success('You have successfully signed in with ' + provider + '!');
$rootScope.$broadcast('session',2)
})
.catch(function(error) {
if (error.error) {
// Popup error - invalid redirect_uri, pressed cancel button, etc.
toastr.error(error.error);
} else if (error.data) {
// HTTP response error from server
toastr.error(error.data.message, error.status);
} else {
toastr.error(error);
}
});
};
expecting a token named token error here
service is called on broadcast
api/me 404 error here
var app = angular.module('app');
app.factory('Account', function($http) {
return {
getProfile: function() {
return $http.get('api/me');
},
updateProfile: function(profileData) {
return $http.put('api/me', profileData);
}
};
});
I've tried all the variations on the github page there doesn't seem to be a solid solution for this.
Thought it might be because of the # in the url
changed the base url to /# and got error.
I added
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
that doesn't work either, what am I doing wrong?
I think the error is when you are returning a JSON response from your server.
the format of the JSON response should be in the format.
{ "token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0.yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw"}
so check what JSON response you are getting. and if you need more info on it check the issues tab of the GitHub link you have provided.

Internal Server Error when using Meteor.loginWithFacebook

Using the service-configuration and accounts-facebook packages, after clicking on the facebook button and logging in from the Facebook authorization window that pops up, we're getting an Internal server error when performing a Meteor.loginWithFacebook.
This was tested on a very basic example, what is causing this error?
Template.login.events({
'click .btn-facebook': function (ev) {
Meteor.loginWithFacebook({}, function(error) {
if(error) {
throw new Meteor.Error('Facebook login failed: ', error);
}
})
}
});
/server/lib/config/social.js
Meteor.startup(function() {
ServiceConfiguration.configurations.update(
{ service: "facebook" },
{ $set: {
appId: "xxx",
secret: "xxx"
}
},
{ upsert: true }
);
})
Error (server side)
Exception while invoking method 'login' undefined
Error (client side)
Error: Internal server error [500]
at _.extend._livedata_result (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:4964:23)
at onMessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:3725:12)
at http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:2717:11
at Array.forEach (native)
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
at _.extend._launchConnection.self.socket.onmessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:2716:11)
at REventTarget.dispatchEvent (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:156:22)
at SockJS._dispatchMessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:1141:10)
at SockJS._didMessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:1199:18)
at WebSocket.SockJS.websocket.that.ws.onmessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:1346:17)
I had the same issue, and solved it like this :
After checking that you have configured your schema as described here :
Schema.User = new SimpleSchema({
_id: {
type: String
}
...
});
You should add the second part into an Accounts.onCreateUser like this, into server/accounts.js for example :
Accounts.onCreateUser(function (options, user) {
if (user.services.facebook) {
user.emails = [{
address: user.services.facebook.email,
verified: true
}];
}
return user;
});
It will append the facebook email to the newly created account. The error should disapear.

Auth to NickServ via Node.js IRC

How can I log in to NickServ in Node.js with IRC module?
I have tried using NickServ module, this is the reply (my nick is in a group):
error: { prefix: 'irc.cccp-project.net',
server: 'irc.cccp-project.net',
command: 'err_notregistered',
rawCommand: '451',
commandType: 'error',
args: [ '*', 'Register first.' ] }
Using IRC module:
bot.say("nickserv", "identify " + password);
error: { prefix: 'irc.cccp-project.net',
server: 'irc.cccp-project.net',
command: 'err_notregistered',
rawCommand: '451',
commandType: 'error',
args: [ '*', 'Register first.' ] }
I also tried How do you login with node-irc?
Here you can see your error:
http://www.mirc.org/mishbox/reference/rawhelp4.htm#raw451
You have to wait to join a channel until your client is fully connected. A solution is that you tell the constructor to join your channel:
var irc = require('irc');
var client = new irc.Client('irc.yourserver.com', 'myNick', {
channels: ['#channel'],
});
from: https://www.npmjs.com/package/irc
While the answer provided by #Kyroy works, the actual thing you need to hook on is the registered event:
var irc = require('irc');
var client = new irc.Client('irc.yourserver.com', 'myNick');
client.addListener('registered', function() {
client.say('nickserv', 'identify ' + password);
})

Categories