How to connect socket.io and rethinkdb? - sockets

After hours of trying. I haven't make it work.
Here's what I have.
var app = require('express')(),
http = require('http').Server(app),
io = require('socket.io')(http),
r = require('rethinkdb');
http.listen(5000);
console.log('Server started on port 5000');
r.connect({db: 'testRealtime'}).then(function(c) {
r.table('messages').insert(
{ message: "realtime" }
)
r.table('messages').changes().run(c)
.then(function(cursor) {
cursor.each(function(err, item) {
io.emit('messages', item)
})
})
})
As you can see on the above example. I am trying to insert a message realtime and look at it on rethinkdb dashboard. But this doesn't work. I don't know why.
Rethinkdb query r.db('testRealtime').table('messages').changes()
Since i'm using angular2. Here's the Service I created
import * as io from 'socket.io-client'
export class ChatService {
private url = 'http://localhost:5000'
private socket;
getMessages() {
this.socket = io(this.url);
this.socket.on('messages', function(data){
console.log(data.new_val.query_engine)
})
}
}
On my component, I just call the getMessages form service. Nothing to worry about angular code. I think it is more about the connection of socket.io and rethinkdb.
Any help would be appreciated. Thanks.

Related

socket.io for react native (sending query problems)

I'm using this library and i can connect without problems.
Usually when I have worked with sockets the code that ever i used is:
socket = io.connect(url, { query: ‘token=’ + token});
and i can see this info reading socket.request._query
Using socket.io for react native i'm trying to send params:
this.socket = new SocketIO('http://localhost:3000', { query: ‘token=’ + token});
but in socket.request._query only can see this log:
{ transport: 'polling', b64: '1' }
In the library some options are mentioned like: connectParams. But i don't know how i can see the info
Related: link
It's not pretty detailed in the repo, but connectParams is a key/value object, and furthermore the values you sent in it will be appended in the url, as shown here:
if connectParams != nil {
for (key, value) in connectParams! {
let keyEsc = key.urlEncode()!
let valueEsc = "\(value)".urlEncode()!
queryString += "&\(keyEsc)=\(valueEsc)"
}
}
>Source<
So, you should try using connectParams like this(though I'm not sure how you tried it before):
this.socket = new SocketIO('http://localhost:3000', {
connectParams: {
myAwesomeQueryStringParam: "someRandomValue"
}
});
PS: forgive me, my english is pretty bad

Editing My HTTP Call to Use Sockets (socket.io) to Receive Data via an Observable in my Angular 2 App

Right now I have an http get call handling data coming from an api into my Angular 2 app. Now we're switching to using sockets via socket.io. I have been using an observable to get the data, and I know I can continue to do that while using socket.io sockets. But I'm having difficulty figuring out exactly what it should look like - i.e., how I need to edit my getByCategory function call to receive the data via a socket connection. This is what my getByCategory function currently looks like in my client-side Angular service:
private _url: string = 'https://api.someurl';
getByCategory() {
return this._http.get(this._url)
.map((response:Response) => response.json())
.catch(this._errorsHandler);
}
_errorsHandler(error: Response) {
console.error(error);
return Observable.throw(error || "Server Error");
}
And, on the server side, this is what my function export looks like in our mongoDB setup (already set up to use sockets via socket.io):
exports.getByCategory = function(req, res, next) {
let skip, limit, stage, ioOnly = false;
let role='office_default';
if (_.isUndefined(req.params)) {
stage = req.stage;
skip = parseInt(req.skip) || 0;
limit = parseInt(req.limit) || 0;
role = req.role;
ioOnly=true;
}
else {
stage = req.params.stage;
skip = parseInt(req.query.skip) || 0;
limit = parseInt(req.query.limit) || 0;
role = req.query.role;
}
console.log(role);
Category[role].find({'services.workflow.status': stage}).skip(skip).limit(limit).exec(function(err, doc) {
if (err) { if (!ioOnly) { return next(err) } else { return res(err)}}
else if(doc) ((!ioOnly) ? res.json(doc) : res(doc));
else ((!ioOnly) ? res.sendStatus(204) : res(doc));
});
};
How should I edit my getByCategory function to use socket.io instead of http in my service? Do I need an emit function coming from my api to act on in my Angular 2 service - or can I just adjust my current getByCategory function to use sockets within the existing observable instead?
I thought about editing the function to look something like this:
getByStage() {
this.socket.on('getByCategory')
.map((response:Response) => response.json())
.catch(this._errorsHandler);
}
}
... but to do that I'd need the server function export to make it available via an "emit" or something similar, wouldn't I? Would it work if I did that? Am I missing something here?
If you need to work with socket connection (like socket.io), you should depend on callbacks.
So, you should set up callback functions to work with them.
A demo is given here-
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
import * as io from 'socket.io-client';
export class ChatService {
private url = 'http://localhost:5000';
private socket;
sendMessage(message){
this.socket.emit('add-message', message);
}
getMessages() {
let observable = new Observable(observer => {
this.socket = io(this.url);
this.socket.on('message', (data) => {
observer.next(data);
});
return () => {
this.socket.disconnect();
};
})
return observable;
}
}
A complete tutorial of using Angular2 with socket.io is given here.
Hope you have your answer.

pg-promise hangs after six queries

I'm working on a project using pg-promise. I've tried querying a few different ways with pg-promise but they all seem to cause it to hang after 6 queries.
It seems to me like the connections aren't being closed but I can't find anything in the documentation about closing a connection after a query.
Here's what I have
var cn = {
host: 'localhost',
port: 5432,
database: 'db',
user: 'user',
password: 'password'
};
var db = pgp(cn);
function query(sql, params) {
return db.task(function (t) {
// this = t = task protocol context;
// this.ctx = task config + state context;
return t.query(sql, params);
})
.then(function (events) {
// success;
console.log(events);
})
.catch(function (error) {
// error;
});
}
I also tried using a shared connection, object but the documentation recommended using tasks. Does anyone know what's going on here?
I'm not sure if this will be helpful to anyone in the future. But my problem was not return requests to the browser.
I hit the maximum number of connections and no responses to the browser made it appear to be hanging to me. I didn't realize requests is node/express won't automatically return like they do with php/apache.

Meteor code must always run within a fiber when deploy in meteor server

I kept having this error when i deploy my app onto meteor cloud server.
Meteor code must always run within a Fiber
at _.extend.get (app/packages/meteor/dynamics_nodejs.js:14:13)
at _.extend.apply (app/packages/livedata/livedata_server.js:1268:57)
at _.extend.call (app/packages/livedata/livedata_server.js:1229:17)
at Meteor.startup.Meteor.methods.streamTwit (app/server/server.js:50:24)
however, I have already wrapped within Fibers
streamTwit: function (twit){
var userid = '1527228696';
twit.stream(
'statuses/filter',
{ follow: userid},
function(stream) {
stream.on('data', function(tweet) {
Fiber(function(){
if(tweet.user.id_str === userid)
{
Meteor.call('addQn', tweet);
}
}).run();
console.log(tweet);
console.log('---------------------------------------------------------');
console.log(tweet.user.screen_name);
console.log(tweet.user.name);
console.log(tweet.text);
});
}
);
}
I don't know what's the reason but someone suggested that i should wrap it with Meteor.bindEnvironment instead. Hence, I did this:
streamTwit: function (twit){
this.unblock(); // this doesn't seem to work
console.log('... ... trackTweets');
var _this = this;
var userid = '1527228696';
twit.stream(
'statuses/filter',
{ follow: userid},
function(stream) {
stream.on('data', function(tweet) {
Meteor.bindEnvironment(function () {
if(tweet.user.id_str === userid)
{
Meteor.call('addQn', tweet);
}
}, function(e) {
Meteor._debug("Exception from connection close callback:", e);
});
console.log(tweet);
console.log('---------------------------------------------------------');
console.log(tweet.user.screen_name);
console.log(tweet.user.name);
console.log(tweet.text);
});
}
);
}
//add question method
addQn:function(tweet){
questionDB.insert({'tweet': tweet, 'date': new Date()});
}
but now it doesn't even work. I realise that this only happened when I tried to insert some data into mongodb.
May I know what is the problem with my code? Thanks!
All these codes were written in app/server/server.js
You shouldn't need to use Meteor.call on the server side. That is for client-side code only. Just call addQn directly or better yet, inline it since it's just one line of code.

AngularJS Testing a Service with $http and $q

I'm new to AngularJS and to JS testing in general and I'm having trouble wrapping my mind around how to go about testing this rather simple service. I've tried using $httpBackend with 'when' and 'expect' GET in variations configurations, to no avail. The test should verify that 1) data is returned via the deferred.resolve and 2) no data is returned via the deferred.reject. If someone could point me in the right direction i'd be quite grateful. Thanks!
btw: I'm using Jasmine + Testacular
.service('myService', function($http, $q) {
return {
getMyData: function() {
var deferred = $q.defer();
$http.get('/foo/bar.do').success(function(data) {
deferred.resolve(data);
}).error(function(){
deferred.reject();
});
return deferred.promise;
}
}
})
I had kind of the same problem testing a service with $http and $q.
Here is one of my test which passes:
it('should issue a GET request to /foo/bar.do', inject(function ($httpBackend) {
$httpBackend.when('GET', '/foo/bar.do').respond('success');
var finalResult = '';
var result = myService.getMyData();
result.then(function(data) {
finalResult = data;
}, function() {
console.log('error');
});
$httpBackend.flush();
expect(finalResult).toBe('success');
}));