I've got problem connecting Flash client to Node.js server.
Short story:
For a first time I'm building a Node.js server that should be used by both web client (WebSocket) as well as a Flash client (Socket). The web client, of course, works like a charm, but I can't get over the Flash one. I get SECURITY_ERROR. After a day of research I think it's because of the policy file not being loaded. Ideas (primus on top of engine.io) ?
Long story:
I'm using Primus as I thought I'll need it because I have both web sockets and flash sockets to handle. Not sure if this is accurate? :)
I'm using Engine.io as a 'transformer/transporter' - the main framework that the layer uses. I won't discuss the standard web client (using Chrome and primus-client), as it's easy to setup.
I'm using simple and standard Sockets in AS3:
_socket = new Socket();
_socket.addEventListener(Event.CONNECT, onSocketConnect);
//...
_socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
_socket.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
_socket.connect('localhost', '1337);
When building it within Flash IDE, it goes to the onSocketConnect function, but if I try to write anything to the socked - I get disconnected. If I run this from the web browser, I get into the onSecurityError method.
I must say that I don't get any traces in the node console!
primus.on('connection', function connection(spark) {
console.log('new connection'); // never gets logged!
As I know, security error is thrown when there is error with the policy file, so I started searching for a solution for that.
I've read a lot of things online, and most common solution was simple usage of socket.io and so called FlashSocket.IO. I tried implementing it, but it's so old, that some of the code is a kind of missing and I finally got some errors from the hurlant library - I couldn't get it working.
I also saw some node package called policy, which runs separate server to server the policy file.
I tried adding a transport array with flashsocket in it - no change. I also can't understand why all of the samples are using transports - I've searched and both index.js and primus.js are using transport (why there are two separate files, Jesus?!)
I could try using only engine.io without primus, but I don't know if this would be of any help. All the posts and samples I've found are pretty old - please help me with any up to date solution or at least some explanation what needs to be done - seems like a whole new universe to me :)
Thanks in advance!
Edit:
Thanks to the The_asMan, I figured out it has something to do with the handshake. I've tried this simple example (despite the fact it's so old) - it worked perfectly for the Flash client! Of course I cannot connect web sockets to it, as the handshake is not proper - it has some kind of protocol for it.
So I guess I just have to understand how to get the <policy-file-request/> in node - I'll be able to return the policy file. But I don't know how to get it - I don't receive any kind of data nor connect handler...
You have a cross domain policy issue.
I answered it all here.
AS3 - Flash/AIR Socket Communication writeUTFBytes only works once
just an idea:
On some operating systems, flush() is called automatically between execution frames, but on other operating systems, such as Windows, the data is never sent unless you call flush() explicitly. To ensure your application behaves reliably across all operating systems, it is a good practice to call the flush() method after writing each message (or related group of data) to the socket.
Related
I am new to Socket IO development. I wanted to know the following around it :
MAX limit for the number of concurrent OPEN Sockets supported ?
Guidelines / extra care to be taken to fine-tune the Node Server for Production.
Does socket.io ensure message deliver ? or it is send-and-forget ? Also are there any node-modules which when installed leverage this feature ?
In case socket.io does not support message delivery; how can I ensure that the message was sent and received successfully to the intended person ?
MAX limit for the number of concurrent OPEN Sockets supported ?
This depends entirely on your environment, your application, and its configuration. Socket.IO has many potential transports, some of which don't even require a persistent connection. There is no simple answer to this question, and nor should there be. This is the wrong question to ask. In a usual scenario, Socket.IO isn't going to be your bottleneck... your application itself will be. What you should be asking about is how to scale your application as you grow... and the answer to that is dependent on the specifics of how your application works.
Guidelines / extra care to be taken to fine-tune the Node Server for Production.
There are entire books on this. Start with the Node.js documentation.
Does socket.io ensure message deliver ?
Socket.IO when used in default configuration is a reliable transport. Of course things can always get lost... it's the internet after all... but yes, retries will happen. I've found this is one of the best parts of Socket.IO, is that if you need to ensure a message is going to get there, it does its best to do that.
Also are there any node-modules which when installed leverage this feature ?
What feature?
In case socket.io does not support message delivery; how can I ensure that the message was sent and received successfully to the intended person ?
Yes, you can deliver messages with Socket.IO... that's sort of the whole point. As far as whether data made it to the right person, you just need to send it to the right place. Remember though that someone else could always be sitting at the computer....
I'm struggling with a technical issue, and because of I'm pretty new on NodeJS world I think I don't have the proper good practise and tools to help me solve this.
Using the well known request module, I'm making a stream proxy from a remote server to the client. Almost everything is fine and working properly until a certain point, if there is too much requests at the same time the server does no longer respond. Actualy it does get the client request but is unable to go through the stream process and serve the content.
What I'm currently doing:
Creating a server with http module with http.createServer
Getting remote url from a php script using exec
Instanciate the stream
How I did it:
http://pastebin.com/a2ZX5nRr
I tried to investigate on the pooling stuff and did not understand everything, same thing the pool maxSocket was recently added, but did not helped me. I was also seting before the http.globalAgent to infinity, but I read that this was no longer limited in nodeJS from a while, so it does not help.
See here: https://nodejs.org/api/http.html#http_http_globalagent
I also read this: Nodejs Max Socket Pooling Settings but I'm wondering what is the difference between a custom agent and the global one.
I believed that it could come from the server but I tested it on a very small one and a bigger one and it was not coming from there. I think it definitely coming from my app that has to be better designed. Indeed each time I'm restarting the app instance it works again. Also if I'm starting a fork of the server meanwhile the other is not serving anything on another port it will work. So it might not be about ressources.
Do you have any clue, tools or something that may help me to understand and debug what is going on?
NPM Module that can help handle stream properly:
https://www.npmjs.com/package/pump
I made few tests, and I think I've found what I was looking for. The unpipe things more info here:
https://nodejs.org/api/stream.html#stream_readable_unpipe_destination
Can see and read this too, it leads me to understand few things about pipe remaining open when target failed or something:
http://www.bennadel.com/blog/2679-how-error-events-affect-piped-streams-in-node-js.htm
So what I've done, i'm currently unpiping pipes when stream's end event is fired. However I guess you can make this in different ways, it depends on how you want to handle the thing but you may unpipe also on error from source/target.
Edit: I still have issues, it seams that the stream is now unpiping when it does not have too. I'll have to doubile check this.
Brief Description:
Well, since many days I've been looking for an answer to this question but there seems to be answers for 'How to create a Push Notification Server' and like questions. I am using node.js and it's quite easy to 'create' a push notification server using sock.js (I've heard socket.io isn't good as compared to sock.js). No problem till here. But what I want is how to model such a server.
Details:
OK, so, let's say I've an application where there's a chat service (just an example this is, actual thing is big as you might have guessed). A person sends a message in a room and all the people in the room get notified. But what I want is a 'stateful' chat - that is, I want to store the messages in a data store. Here's where the trouble comes. Storing the message in the database and later telling everyone that "Hey, there's a message for you". This seems easy when we need the real-time activity for just one part of the app. What to do when the whole app is based on real-time communication? Besides this, I also want to have a RESTful api.
My solution (with which I am not really happy)
What I thought of doing was this: (on the server side of course)
Data Store
||
Data Layer (which talks to data store)
||
------------------
| |
Real-Time Server Restful server
And here, the Real-time server listens to interesting events that the data-layer publishes. Whenever something interesting happens, the server notifies the client. But which client? - This is the problem with my method
Hope you can be of help. :)
UPDATE:
I think I forgot to emphasize an important part of my question. How to implement a pub-sub system? (NOTE: I don't want the actual code, I'll manage that myself; just how to go about doing it is where I need some help). The problem is that I get quite boggled when writing the code - what to do how (my confusion is quite apparent from this question itself). Could please provide some references to read or some advice as to how to begin with this thing?
I am not sure if I understood you correctly; but I will summarize how I read it:
We have a real-time chat server that uses socket connections to publish new messages to all connected clients.
We have a database where we want to keep chat logs.
We have also a restful interface to access the realtime server to get current chats in a lazier manner.
And you want to architect your system this way:
In the above diagram, the components I circled with purple curve wants to be updated like all other clients. Am I right? I don't know what you meant with "Data Layer" but I thought it is a daemon that will be writing to database and also interfacing database for other components.
In this architecture, everything is okay in the direction you meant. I mean DataStore is connected by servers to access data, maybe to query client credentials for authentication, maybe to read user preferences etc.
For your other expectation from these components, I mean to allow these components to be updated like connected clients, why don't you allow them to be clients, too?
Your realtime server is a server for clients; but it is also a client for data layer, or database server, if we prefer a more common naming. So we already know that there is nothing that stops a server from being a client. Then, why can't our database system and restful system also be clients? Connect them to realtime server the same way you connect browsers and other clients. Let them enjoy being one of the people. :)
I hope I did not understand everything completely wrong and this makes sense for the question.
I'm developing a sort of Flash Operator Pannel for Asterisk but, with Node.js and Socket.io instead of depending of Flash.
I've polished the node server and the front end BUT I don't know how could I send events from Asterisk to node server and do things that will be sended over the socket.
Given the fact that we have a heavily tuned Asterisk to suit our company needs, connecting to the AMI nor the Asterisk socket will solve my problem because we aren't working with real extensions.
So, despite the Asterisk part, I want to know how could I send info to node through bash or curls or whatever
I thought about using curls to the server but this could cause that someone who knows the commands (pretty unlikely) could alter the application flow with unreal data.
EDIT: Rethinking about it, I would just want to be able to receive requests through the socket/server ??? and then be able to perform actions that will be emited through socket.io.
Is that even possible?
The answer really depends upon what specific data you are trying to get from Asterisk to Node. You're trying to replace the Flash Operator Panel, yet you don't have real extensions. I'm guessing that you are using Asterisk as an SBC/proxy of sorts.
If you truly want an event-driven approach, I suggest modifying your dialplan to reach out to Node whenever needed, with whatever data you want. This would most easily be achieved by calling an AGI script with some number of arguments (written in whatever language) that then connects to Node via an HTTP POST, socket, or other.
If you want a more passive approach, you could have Node stream-read the asterisk log files for data, or, as already suggested, connect to the Asterisk Manager Interface (AMI) and stream from there. Contrary to what has been stated previously, I don't consider this to be a very daunting task.
You want to open a socket from Node to Asterisk's AMI (asterisk manager interface). I never used Node, but I would imagine the code would look roughly like this:
var astman = new net.socket().connect(5038);//connect to port 5039 on localhost
astman.on('data', function(data) {
//do something with received data
});
One of the most well maintained ami libraries are FreePBX's php-astmanager. While it's written in php, it should give you a pretty good idea of what your need to do.
You could certainly set up your node.js program to listen on a socket for messages from Asterisk. But you'd have to roll your own connection management scheme, authentication scheme, message durability (possibly), etc.
Alternatively -- and especially if there is the node server and asterisk server are not on the same machine -- you could use a message queue program like RabbitMQ. That takes care of a lot of the important details involved in interprocess communications. It's pretty easy, too. On the node side, check out https://github.com/postwait/node-amqp
I've never used Asterisk but running command line programs can be done with the child_process module.
http://nodejs.org/docs/latest/api/child_processes.html
I'd like to send messages through a socket to specific clients but can't seem to figure out how to do it without socket.io. The reason I can't use socket.io is because I'm trying to connect to a flash client, and I've read in numerous threads here on stackoverflow that socket.io isn't meant to connect to a flash clent. I have working code that will connect a node socket server to a socket client created in flash (actionscript 3), but it broadcasts the info to everyone connected to the socket. What I thought was if there was some way to send info to specific socket ids then I'd be in business. I looked in the docs and didn't find any info on how to do this, but then again I couldn't find any documentation about specific socket ids in the docs either, yet using "socket.id" will give the id so I'm wondering if there is some undocumented way to do this.
And just FYI this is for a card game where each player connected just gets their cards sent to them. The game logic is taken care of server side and I have that working. Now I just need to get each player only the info they need. Thanks.
Darryl
I know for sure you can use Adobe® Flash® Socket in conjunction with socket.io. When you look at the available transports(browsers) you will notice that socket.io also supports Adobe® Flash® Socket. But to be honest I do not know the exact details about this, but I think you can learn them by studying socket.io's specification page.
When looking at socket.io's WIKI I also found there already is a library to use socket.io with Adobe® Flash® Socket. The library is called FlashSocket.IO which I believe can help you although I don't know any flash myself.
Adobe® Flash® Socket is standard disabled in the latest socket.io branches, but you can enable them easily by studying configuring socket.io. This page tells you how to enable all tranports which I will summarize below:
io.set('transports', [ // enable all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
If you have not yet had suffice answer(I think this should help you) I think you could also file an issue at socket.io's issue page, because I find the socket.io's maintainers are super friendly and will tell you how to accomplish this without the least pain.
Finally to accomplish this using plain node you will have to keep track of all the active socket connections(sessions) yourself and only send that message to that specific socket. This is a mundane task, but I think there are more than enough tutorials available that teach you this(you could also look at socket.io how they achieve this, although this is a pretty large project/codebase).
I hope this answered your question. If not, I recommend you to ask a question in the comments for example.