ptejada / apepubsub Goto Github PK
View Code? Open in Web Editor NEWA PubSub JavaScript Framework for the APE Server
License: MIT License
A PubSub JavaScript Framework for the APE Server
License: MIT License
If you call unSub to unsubscribe from a channel that you are not connected to it throws a JavaScript error
Uncaught TypeError: Object false has no method 'leave' ApePubSub.js:399
APS.unSub ApePubSub.js:399
bec.on.ready aps_start.js:88
APS.trigger ApePubSub.js:206
APS.onMessage ApePubSub.js:476
ws.onmessage ApePubSub.js:672
unSub should just return false or some other error if channel is not created.
The framework already saves the name property of a user to be unique, but it fails to check for it on the connect hook. A simple if statement would take care of that.
The solution would also implement the NAME_USED error 007.
Currently if sessions are used, the user can only be connected from one point(client instance) at a time. For example if a user is connected to a channel in a browser tab and opens another tab, the user would be disconnected from the first tab once connected in the second.
A new multi branch has been created, strictly for developing purposes
Hi
I tried to run apepubsub with the current ape but looks like it failed
I have build it from source ( 1.1.3-DEV Latest from git ) and running it on a ubuntu server.
When I try to run a apepubsub demo, it throws this error
[APS] Adding [music] event 'join' to queue ApePubSub.min.js:20
[APS] Adding [music] event 'left' to queue ApePubSub.min.js:20
[APS] Adding [music] event 'message' to queue ApePubSub.min.js:20
[APS] Adding [music] event 'joined' to queue ApePubSub.min.js:20
[APS] <<<< RESTORE >>>>
Object {cmd: "RESTORE", chl: 0, freq: "8", params: Object, sessid: "af0e8efaf489168a36b7ba43aeb46567"}
ApePubSub.min.js:20
[APS] >>>> ERR <<<< Object {code: "003", value: "BAD_CMD"}
But it works on your demo server! Which specific version of 1.1.3-DEV ( Git Hash Please) are you using ? Or are there any compatibility issues ?
When different commands are sent to the server at the same time with the sync command, the user that sent the command doesn't received the sync event
The command is sent with something similar to this: APS.getChannel(channel).send("userWriting", {"writing": false}, true);
I enabled debug for you to see the trace. In this example, four messages are sent (1, 2, 3, 4) and only 1 and 4 are received by the user.
[APS] >>>> SYNC <<<<
Object {data: Object, event: "userWriting", chanid: "fc0462ffb6fa0d9beb43bba13df6a8d0"}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0] on client
APS {option: Object, identifier: "APS", version: "1.5.1", state: 1, _events: Object…}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0]
APS.channel {name: "apechat_room_21", _events: Object, pubid: "fc0462ffb6fa0d9beb43bba13df6a8d0", _client: APS, update: function…}
ApePubSub.js:475
[SENDING: chatMsg] 1 chat_APS.js:528
[SENDING DONE] 1 chat_APS.js:533
[APS] >>>> SYNC <<<<
Object {data: Object, event: "chatMsg", chanid: "fc0462ffb6fa0d9beb43bba13df6a8d0"}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ chatmsg }}}[0]
APS.channel {name: "apechat_room_21", _events: Object, pubid: "fc0462ffb6fa0d9beb43bba13df6a8d0", _client: APS, update: function…}
ApePubSub.js:475
[RECEIVING] 1 chat_APS.js:325
[APS] >>>> SYNC <<<<
Object {data: Object, event: "userWriting", chanid: "fc0462ffb6fa0d9beb43bba13df6a8d0"}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0] on client
APS {option: Object, identifier: "APS", version: "1.5.1", state: 1, _events: Object…}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0]
APS.channel {name: "apechat_room_21", _events: Object, pubid: "fc0462ffb6fa0d9beb43bba13df6a8d0", _client: APS, update: function…}
ApePubSub.js:475
[SENDING: chatMsg] 2 chat_APS.js:528
[SENDING DONE] 2 chat_APS.js:533
[APS] >>>> SYNC <<<<
Object {data: Object, event: "userWriting", chanid: "fc0462ffb6fa0d9beb43bba13df6a8d0"}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0] on client
APS {option: Object, identifier: "APS", version: "1.5.1", state: 1, _events: Object…}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0]
APS.channel {name: "apechat_room_21", _events: Object, pubid: "fc0462ffb6fa0d9beb43bba13df6a8d0", _client: APS, update: function…}
ApePubSub.js:475
[SENDING: chatMsg] 3 chat_APS.js:528
[SENDING DONE] 3 chat_APS.js:533
[APS] >>>> CLOSE <<<< Object {value: "null"} ApePubSub.js:475
[APS] >>>> SYNC <<<<
Object {data: Object, event: "userWriting", chanid: "fc0462ffb6fa0d9beb43bba13df6a8d0"}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0] on client
APS {option: Object, identifier: "APS", version: "1.5.1", state: 1, _events: Object…}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0]
APS.channel {name: "apechat_room_21", _events: Object, pubid: "fc0462ffb6fa0d9beb43bba13df6a8d0", _client: APS, update: function…}
ApePubSub.js:475
[SENDING: chatMsg] 4 chat_APS.js:528
[SENDING DONE] 4 chat_APS.js:533
[APS] >>>> SYNC <<<<
Object {data: Object, event: "chatMsg", chanid: "fc0462ffb6fa0d9beb43bba13df6a8d0"}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ chatmsg }}}[0]
APS.channel {name: "apechat_room_21", _events: Object, pubid: "fc0462ffb6fa0d9beb43bba13df6a8d0", _client: APS, update: function…}
ApePubSub.js:475
[RECEIVING] 4 chat_APS.js:325
[APS] >>>> SYNC <<<<
Object {data: Object, event: "userWriting", chanid: "fc0462ffb6fa0d9beb43bba13df6a8d0"}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0] on client
APS {option: Object, identifier: "APS", version: "1.5.1", state: 1, _events: Object…}
ApePubSub.js:475
[APS] [channel] [apechat_room_21] {{{ userwriting }}}[0]
APS.channel {name: "apechat_room_21", _events: Object, pubid: "fc0462ffb6fa0d9beb43bba13df6a8d0", _client: APS, update: function…}
I'll try to optimise my code and provide more info.
Code: client.pub("channel", "été", false);
Error 005 "BAD_JSON" is fired because of the characters "é". If I add "encodeURIComponent" to the "été" string, the string is passed to the other client and "decodeURIComponent" is required to get back the characters "é".
On my local machine I have mydomain.dev
and {number}.mydomain.dev
for APE.
For mydomain.dev
to work, I just added it to /etc/hosts
.
For {number}.mydomain.dev
to work, I installed bind9
dns server.
When I stop bind9
the {number}.mydomain.dev
does not work and in browser console I get
The dead
event is triggered twice, but with different state
.
state
parameter means?See screenshot: https://dl.dropbox.com/u/28560717/firefox_websocket.png
This is not really an issue since it doesn't break my app workflow.
That doesn't happen in Chrome.
This error doesn't really breaks the framework or an application workflow but it sends an unnecessary request through the wire and i want to fix that.
Hi
I just moved into ApePubSub, and in my application all users bind to specific channels ( eg: user_ ). I used to send notifications to the users based on the channel.
In APE_JSF I used to use the inlinepush from php. But in APS I find no equivalent. I saw the php example, but that one only forwards the commands based on user action, but in my case it is triggered via the server and it has no-notion of pipe, it only knows the channel.
How can I achieve the similar functionality ?
I'm trying to use APS with another JS library (Linq2IndexedDb), but I received an error on almost any event in Google Chrome.
After some debugging, I realized the error was caused by these lines in the other library:
Array.prototype.contains = function (obj) {
return this.indexOf(obj) > -1;
};
It's a simple extension of Array, but it added an "undefined event" during onMessage loop (onMessage.js, line 16).
Using a simple for loop:
for(i=0;i<data.length;i++){ ... }
instead of the one provided:
for(var i in data) {... }
solved my problem, but I'm not sure whether it could happen again somewhere else, 'cause I've seen many similar loops in other parts of the script.
Is there another way to solve this problem?
I am building a multi-language site and use ApePubSub to send events from php via inlinepush
command to the users browsers (to update a block on the homepage, to check for new messages in chat when there appears one) then the browsers does ajax requests to the php server to get the data (I don't send any data through APE, only events when something happens).
I connect the browser to 3 channels:
"main"
- events for all users (for e.g. to update the Recent Site Activity block on the frontpage)"main:{locale}"
("main:en"
, "main:fr"
, ...) - events for users browsing a concrete locale (for e.g. a chat exists only in a single locale site.com/en/chat/123
, it does not exist in other locales site.com/fr/chat/123
is 404 page)"user:{username}"
- a separate channel for each logged in user, to send events only to him (for e.g. when he receives a private message, or a notification that he was banned)The problem was with session and the "main:{locale}"
channel:
site.com/en
and I am subscribed to the main:en
channelsite.com/fr
main:en
channel)main:fr
channelNow in both tabs I am subscribed to both main:en
and main:fr
. So in the fr
locale I receive events which was meant for the en
locale, which is not what I wanted to achieve.
I could leave the user connected to both locale channels, and just write my code to ignore events that comes from the locales that he is not currently on. But if the user is currently in the fr
locale, where there is no activity, he may receive a bunch of events from the en
locale which has a lot of activity, this is traffic waste and APE server load.
I disabled the session {session: false}
. Now the problem with locale channels is resolved (on every refresh the browser creates a new connection and subscribes to correct channels), but this creates another problem: Every refresh creates a new user in the channels, and I am afraid that this will cause overhead for the APE server (it will store 10000 connections which only 1000 are real/active). I know that the connection is closed after some seconds of inactivity, but this may not help when the site will be frequently accessed and the APE server will be flooded with connections.
Can you recommend something to solve this problem?
Now I am thinking, if I will be able to manually create/recover sessions, I would create a separate session for each locale: If the session "{some_id}:{locale}"
exists, restore it, else create it.
https://github.com/ptejada/ApePubSub/wiki/Getting-started
On this page its unclear if you prefer the binary installation or building your own binaries? I would edit the page but not sure which way you actually prefer.
This is a MINOR issue
If the client has not joined any channe, triggering client.session.destroy() results in an error : Object #<Object> has no method 'destroy'.
Shouldn't this method be always available to clean up cookies ?
If the transport is WS then the capitalization doesn't matter, when the transport is LP. then having upper case letters makes it fail.
Hello Pablo,
After several tests, the 1.3 version breaks (commit: 43ce343) my application :
Client side:
// ape connection
my.apeConnect = function() {
if (window.online) {
var client = new APS(config.servers.ape);
client.user.env = config.env;
client.on('connect', function() {
this.on('ready', function() {
var pubid = this.user.pubid;
if (pubid && pubid !== null) {
myapp.helpers.updateValue('apepubid', pubid);
}
});
});
client.sub('*main');
client.on('push', myapp.events.pushed);
// not logged
} else {
$.removeCookie('APS_session', { path: '/' });
$.removeCookie('APS_chl', { path: '/' });
$.removeCookie('APS_frequency', { path: '/' });
}
};
Server-side (I'm not using the ApePubSub server libraries)
// ape session expired
Ape.addEvent("deluser", function(user) {
if ( user.getProperty('env') !== 'dev' ) {
// removes ape ID in the database
var request = new Http('http://localhost/ape/remove');
request.set('method', 'POST');
request.writeObject({
'pubid': user.getProperty('pubid')
});
}
return true;
});
// manual logout, will trigger "deluser"
Ape.registerCmd("logout", false, function(params, infos) {
var user = Ape.getUserByPubid(params.pubid);
if (user && user !== null) {
user.quit();
}
return {"name":"pushed","data":{"value":"ok"}};
});
// Events
Ape.registerCmd("push", false, function(params, infos) {
var to = Ape.getPipe(params.pubid);
delete params.pubid;
if (to && to !== null) {
to.sendRaw("push", params);
}
return {"name":"pushed","data":{"value":"ok"}};
});
Before investigating further : do you see code that isn't compatible with the newer version ?
In the CHANNEL case, if you use a non-interactive channel USERS are not sent on the connect msg This code failes
case 'CHANNEL':
//this.log(pipe, args);
pipe = new APS.channel(args.pipe, this);
this.pipes[pipe.pubid] = pipe;
this.channels[pipe.name] = pipe;
//====> args.users not in message when non-interactive channel like => *evts
var u = args.users;
var user;
//import users from channel to client
for(var i = 0; i < u.length; i++){
user = this.pipes[u[i].pubid]
if(!user){
this.pipes[u[i].pubid] = new APS.user(u[i], this);
user = this.pipes[u[i].pubid];
}
user.channels[pipe.name] = pipe;
pipe.users[user.pubid] = user;
//Add user's own pipe to channels list
user.channels[user.pubid] = user;
//No Need to trigger this event
//this.trigger('join', [user, pipe]);
}
I use a number colon number as a user number. I can't specify this on
client.user = {
name: usernumber + ':' +randomString(8) //Generates a random name
//What ever you want to store in the user
}
As the client complains of BAD NAME 006
var aps = new APS(
window.location.host, // my APE server is working on "https://([0-9]+).localhost"
{
restored: function() {
console.log('Restore');
},
connect: function() {
console.log('Connect');
},
ready: function() {
console.log('Ready');
}
},
{
debug: true,
secure: true
}
);
aps.connect();
I put here some console.log()s but the execution does not reach them.
I know it's possible to do server side, but is it possible to edit a channel property client side, in the same way we can do it with user properties using user.update({ ... });
?
When channel joined
event is triggered the channel object does not seems ready to send events to the server. The pipe hash seems to be missing from the command send to the server.
In APE_Server/APScripts/framework/cmd_frame.js there is
request.open(\"POST\",\"http://\"+server+\"/0/?\",true);
I think this is hardcode.
When I try to use new APS(..., ..., {secure: true, transport: 'lp'})
on a https site, it gives me an error
For myself I changed that to https
and it works, but I think it should detect the protocol automatically.
Hi Pablo,
I'm working on something which use sessions and have this issue regarding subusers sync.
On my custom server side code, I send an event on a channel: chan.sendEvent('new_stuff', params.data, {"from": info.user.pipe});
Problem is, the sender subusers won't receive "new_stuff". If I remove the "from" option, all user, including the sender subusers, will receive it, but the thing is I don't want the sender to receive it, only his subusers.
I read in the wiki about client.sendEvent and restrict, but I'm not sure how to get the subuser. Ape.log(info)
shows an empty subuser
.
Ortherwise, on client side, when I receive an event from myself (from.pubid == client.user.pubid
for instance), is there a way to test if it's from me or one of my subuser (other tabs)?
A solution would be to change my code so I need all users (and subusers) to receive what I want, but still... If the user is not connected to APE, I would still like the action to be displayed.
Thanks,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.