I have a process that runs in California that wants to talk to a process in New York, using Stomp over Websockets.
Also note that my process is not a web app, but I implemented a stomp over websocket client in C++, in order to connect things up to my backend. Maybe this was or wasn't a good idea. So, I want my client to talk to the server and subscribe, where their client pushed messages.
I was implementing my own server when I saw that ApacheMQ supported Stomp over Websockets. So, I started reading the docs.
It says with the last line under 'configuration' at
http://activemq.apache.org/websockets :
One thing worth noting is that web sockets (just as Ajax) implements ? > the same origin policy, so you can access only brokers running on the > same host as the web application running the client.
it says it again in several related searches such as http://sensatic.net/activemq/activemq-54-stomp-over-web-sockets.html
Is this a limitation of the server or the web client?
With that limitation, if I understand right, the server is not going to accept websocket connections from a client, of any kind, that is not on the same machine?
I am not sure I see the point of that...
If that is indeed its meaning, then how do I get around it in order to implement my scenario?
I've not found that bit of documentation you are referring to but from what I know of the STOMP implementation on the broker this seems incorrect. There shouldn't be any limit to the transport connector accepting connect requests from an outside host by default and I don't think the browser treats the websocket requests the same as it does other things like an Ajax case in terms of the same origin policy.
This probably a case that is best checked by actually trying it to see if it works, I've connected just fine from outside the same host using AMQP over websockets on ActiveMQ so I'd guess the STOMP stack should also work fine.
Related
I'm extremely new to all of this, but from my understanding, websockets allow for a bidirectional transfer of information between browsers. Vert.x is a library that allows for asynchronous I/O. And sockJS is a JavaScript library that attempts to use websockets for communication, and provides fallback options otherwise.
But if I'm writing something in Java using vert.x, I don't quite understand how the pieces fit together. Does vert.x actually support websockets? Or do I need a combination of vert.x and sockJS to make that happen?
HTTP(s) is a stateless protocol, which means that once its job is done it will be idle till the next job is given.
So lets take an example of chat application, assume A is chatting with B using HTTP protocol. B has sent a message which is in server, now until A refreshes the browser, B's message will not appear. That's stateless behavior.
Coming to sockets, which is not stateless. Sockets use ws protocol which is always connected to the server. Taking the same example, now if B sends a message, A's socket will fetch and display to the browser, without the need to refresh. That's how sockets work.
To serve a webpage you need an http server. Similarly to use sockets, sockets server is needed. Which is provided by Vert.x. So Vert.x will start socket server, your browser will listen to that server using clientside sock.js file.
I have a server that uses websockets. It is written in Go. For testing, I have another application written in Go. To test, I start the server, then run the test client. The test client creates websocket connections to the server and does things (basically impersonating user activity). Both the client and the server are using the gorilla/websockets library, and standard browsers also work fine with the server.
This was all working beautifully.
To support non-compliant browsers, I was asked to start using the SockJS Go server library. I did this and the new version works just fine when used from a browser by clients using the SockJS library.
Now for the problem. SockJS does not accept incoming websocket connections. Only connections from the SockJS client. So my testing application doesn't work, and I'm unable to test.
I could recover the old version of my connection code from git and make a separate connection type that uses gorilla/websockets and have my server listen on an additional port that only listens on localhost. This would allow me to test the functionality. The downside is that I have to maintain two versions of essentially the same code, and I wouldn't be testing the real user experience and possibly not find bugs until production.
Ideally the SockJS server, considering it still uses gorilla/websockets as a dependency would automatically accept proper websocket connections, but barring that it seems I'd need a SockJS client library in Go which, as far as I can tell, doesn't exist.
Does anyone have a solution for this? Thanks!
I'm trying to get a better understanding of how the server-side architecture works for WebSockets with the goal of implementing it in an embedded application. It seems that there are 3 different server-side software components in play here: 1) the web server to serve static HTTP pages and handle upgrade request, 2) a WebSockets library such as libwebsockets to handle the "nuts and bolts" of WebSockets communications, and 3) my custom application to actually figure out what to do with incoming data. How do all these fit together? Is it common to have a separate web server and WebSocket handling piece, aka a WebSocket server/daemon?
How does my application communicate with the web server and/or WebSockets library to send/receive data? For example, with CGI, the web server uses environmental variables to send info to the custom application, and stdout to receive responses. What is the equivalent communication system here? Or do you typically link in a WebSocket library into the customer application? But then how would communication with the web server to the WebSocket library + custom application work? Or all 3 combined into a single component?
Here's why I am asking. I'm using the boa web server on a uClinux/no MMU platform on a Blackfin processor with limited memory. There is no native WebSocket support in boa, only CGI. I'm trying to figure out how I can add WebSockets support to that. I would prefer to use a compiled solution as opposed to something interpreted such as JavaScript, Python or PHP. My current application using long polling over CGI, which does not provide adequate performance for planned enhancements.
First off, it's important to understand how a webSocket connection is established because that plays into an important relationship between webSocket connections and your web server.
Every webSocket connection starts with an HTTP request. The browser sends an HTTP request to the host/port that the webSocket connection is requested on. That request might look something like this:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
What distinguishes this request from any other HTTP request to that server is the Upgrade: websocket header in the request. This tells the HTTP server that this particular request is actually a request to initiate a webSocket connection. This header also allows the web server to tell the difference between a regular HTTP request and a request to open a webSocket connection. This allows something very important in the architecture and it was done this way entirely on purpose. This allows the exact same server and port to be used for both serving your web requests and for webSocket connections. All that is needed is a component on your web server that looks for this Upgrade header on all incoming HTTP connections and, if found, it takes over the connection and turns it into a webSocket connection.
Once the server recognizes this upgrade header, it responds with a legal HTTP response, but one that signals the client that the upgrade to the webSocket protocol has been accepted that looks like this:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
At that point, both client and server keep that socket from the original HTTP request open and both switch to the webSocket protocol.
Now, to your specific questions:
How does my application communicate with the web server and/or
WebSockets library to send/receive data?
Your application may use the built-in webSocket support in modern browsers and can initiate a webSocket connection like this:
var socket = new WebSocket("ws://www.example.com");
This will instruct the browser to initiate a webSocket connection to www.example.com use the same port that the current web page was connected with. Because of the built-in webSocket support in the browser, the above HTTP request and upgrade protocol is handled for you automatically from the client.
On the server-side of things, you need to make sure you are using a web server that has incoming webSocket support and that the support is enabled and configured. Because a webSocket connection is a continuous connection once established, it does not really follow the CGI model at all. There must be at least one long-running process handling live webSocket connections. In server models (like CGI), you would need some sort of webServer add-on that supports this long-running process for your webSocket connections. In a server environment like node.js which is already a long running process, the addition of webSockets is no change at all architecturally - but rather just an additional library to support the webSocket protocol.
I'd suggest you may find this article interesting as it discussions this transition from CGI-style single request handling to the continuous socket connections of webSocket:
Web Evolution: from CGI to Websockets (and how it will help you better monitor your cloud infrastructure)
If you really want to stick with the stdin/stdout model, there are libraries that model that for your for webSockets. Here's one such library. Their tagline is "It's like CGI, twenty years later, for WebSockets".
I'm trying to figure out how I can add WebSockets support to that. I
would prefer to use a compiled solution as opposed to something
interpreted such as JavaScript, Python or PHP.
Sorry, but I'm not familiar with that particular server environment. It will likely take some in-depth searching to find out what your options are. Since a webSocket connection is a continuous connection, then you will need a process that is running continuously that can be the server-side part of the webSocket connection. This can either be something built into your webServer or it can be an additional process that the webServer starts up and forwards incoming connections to.
FYI, I have a custom application at home here built on a Raspberry Pi that uses webSockets for real-time communication with browser web pages and it works just fine. I happen to be using node.js for the server environment and the socket.io library that runs on top of webSockets to give me a higher level interface on top of webSockets. My server code checks several hardware sensors on a regular interval and then whenever there is new/changed data to report, it sends messages down any open webSockets so the connected browsers get real-time updates on the sensor readings.
You would likely need some long-running application that incoming webSocket connections were passed from the web server to your long running process or you'd need to make the webSocket connections on a different port than your web server (so they could be fielded by a completely different server process) in which case you'd have a whole separate server to handle your webSocket requests and sockets (this server would also have to support CORS to enable browsers to connect to it since it would be a different port than your web pages).
I would like to see if someone can clarify me some concepts I still don´t get about integration of web applications. Up until now, I´ve been working with CometD and Activemq in a project that´s been there for several years but, for what I´ve seen, there are other options out there much more simpler and supported by the community but I still don´t get the whole picture of options available.
So, for what I understand, at the moment, the most common way of getting server pushed events to a client is using websockets. The implementation is server specific and the most used one seems to be the Jetty one. But, because it requires a websocket compatible browser, there are some frameworks that are able to provide websockets and fall to reverse ajax techniques in case this is not an option, like SockJS, that has an implementation for client and for server side. Based on this, as of spring 4 there are templates that allow you to use SockJS behind the scenes and just provide the client implementation of the code using SockJS and letting the programmer to handle the server side in a more easy way.
Apart from this, brokers can understand the websocket protocol so a broker can receive a message from a web browser and then send a message back directly. There is also the STOMP protocol that brokers also implement that allows the system to send/receive messages through websocket to/from the web browser.
One question I have about this is, is STOMP the protocol always used by the broker to send or receive a message to or from a web browser? Or is just one alternative? What is the difference if it´s the later?
Yet another option I´ve seen is using a framework like camel. In this case, the web browser would talk to the websocket component of camel and from there it could be routed directly to the broker using jms. The benefit I see on this is the possibility of introducing processors as part of the route from the browser to the broker, allowing further security processing and reducing the traffic the broker would have to handle in case of not valid/unauthorized messages. Camel would even be able to listen to messages using the STOMP component what would be yet another routing option.
So, to this point, I don´t know if my understanding is correct or if I miss or misunderstand something. If everything is right, it seems that using a framework like SockJS is the best option available at the moment. The use of Spring 4 to simplify things is an option but not really necessary. If the project requires the integration of different systems using a jms broker, the implementation then falls to use SockJS to send messages to the server side and then just route the messages to the correct system. But at this point, there are the options mentioned before like using camel to route the messages or directly send messages to the broker. What would be the best option, or what would be the differences? If I add STOMP to the problem, what does this protocol give me that I can´t handle just with websockets or camel?
I hope I made myself clear. I think this topic includes several technologies and frameworks and it´s quite difficult to express all my concerns without extending the post to much.
Thanks in advance.
In a nutshell, if you want messaging semantics, you should use a messaging protocol such as STOMP. WebSockets sure can handle communication to browsers just fine, but that's just "any custom communication".
The system design may be cleaner if you design around the convention of topics and messaging. The server backend processes can easily push data to a topic that is propagated to all clients, ideally with no further customization.
Aside from STOMP, there is a similar protocol, MQTT which also can run over websockets. A chat demo is provided by ActiveMQ distribution. MQTT is very hot in the Machine2Machine world "internet of things", but I have used it with success in web-deployments too. MQTT should, at least in theory, run pretty good, with low overhead in phone apps, should you ever consider writing one side by side with your website. Then it can be good to use a single setup to communicate "push" data with your clients. Otherwise, your app may have used MQTT, your browser app would have used plain websocket, your backend would have needed another way to pass async events to clients (via some Camel router or similar) and so forth.
I want to implement messaging over internet. But didn't have IP Public yet.
So I want to ask any one here about sending message to ActiveMQ using JMS over internet?
Could It be done ?
Yes, it exposes a normal TCP based endpoint(by default at port 61616). However, this would not be a recommended deployment model - a better model will be to expose a http based endpoint using a servlet container which internally hands over the message to the activemq broker.
There a lot of good solutions that can do this -
Spring Integration , Apache Camel
Exposing a Webservice endpoint using say Apache CXF (which will bring you a standards based interface), which will internally hand over the message to ActiveMQ.
yes, It can be done. we are currently running a little under a thousand "consumers" which connect to our brokers over the internet.
As to the insecurity of traffic over the internet, i do not agree completely:
exposing a webservice is just as riskfull as exposing the broker. In the end, you are never 100% sure your own code or the code or the underlying application (Apache CXF, Webserver, application server, database server, message broker) contain flaws that could be a security risk. Second to that, HTTP is just as much TCP traffic as ActiveMQ is ( Stomp or openwire protocol)
That being said, you can take all measures to make the risk as small as possible.
we have done the following:
User & Password Required to connect to the broker (ActiveMQ suports a wide range of Authentication solutions and you can roll your own if required)
Switch port to a different number so detection is more difficult
if you have control over the consumers aswell, apply IP filters in the firewall for what ip's can connect to the broker ( unfortunately, this was not possible in our case)
encrypt your messages
We have added an application level Authentication aswell using a token. This way, every message is authenticated in our own application
-> if all of these are implemented, I think you are pretty safe and as a bonus, you do not need the extra layer of webservices ( if this application needs to scale, you will need to scale your webservices equally with your brokers.
Plain connections (openwire) should be fine. It's much simpler to stick with the standard setup than to try setting up web services and whatnot. Just make sure to encrypt the channels with SSL. If you use plain passwords, they can possibly be picked up over public networks (unlikely but anyway) - that's why I prefer SSL.
Actually, ActiveMQ is a very good way to do communication over the Internet since it supports transactions and persistence, making it cope well with network stability issues.
However, you need a public IP (or some NAT/port forwarding solution form a public IP) on the machine running the ActiveMQ server for this to work.