websocket

Deploying an Existing Node.JS App to Nodester

Do you have an existing Node.JS application and a Nodester Node.JS hosting account? Cool! Let’s walk through getting that app deployed for you.

1. Open your command line and cd into your app directory

2. Run “nodester app create <appname>”. (Note: If your starting javascript file is NOT server.js, add its name after the appname on the create command)

3. Update your app’s port address to match the one we assigned via the create app command. (Note: If your app uses websockets, set your client app to use port 80.)

4. Run “nodester app info <appname>”

5. Assuming you already have a git repo, add a nodester remote by running “git remote add nodester <git repo from info command>”.  If you do not have a git repo already, first run “git init” followed by “git add .” and git commit -m “initial commit”

6. Run “git push nodester master”.  This will push and run your existing app to Nodester where it can be reached at http://<appname>.nodester.com.

Does your application use any NPM modules?  If so, you will need to install them to your app’s sandbox and restart your application using the following commands:

7. Run “nodester npm install <appname> <module>”

8. Run “nodester app restart <appname>”

Subsequent git pushes update your Nodester app and restarts it automatically for you. Easy as that :)

websockets

The Websocket API is a new implementation for html5 to support bi-directional communication with server side processes. This is good news since realtime interactions with webservers have not been a very exciting experience so far, although AJAX and XmlHttpRequests have enabled browser based web applications to quickly exchange data with a server. Websockets will be able to keep a direct connection between client and server open until it is closed by one or the other end, which allows a continuous two way stream of data on both ends without having to reestablish a connection over and over again. Only one handshake (opening handshake) is required to open a channel which can then be closed again at any given time by sending an end command, the closing handshake

The current status is described in an IETF draft by the HyBi working group at tools.ietf.org. The WebSocket API is described in a w3 draft.The definition and finalization of the protocol is yet very much work-in-progress and although taking a promising direction there are still various concerns reported in the web world e.g. “Web Sockets and the risks of unfinished Standards”.

Java based open source web socket server projects are jWebSocket, Java-WebSocket.

Not directly websocket related, but taken out of context from the ‘Comet with node.js' presentation(by amix), the Netty project, the Java NIO client server socket framework. “The Netty project is an effort to provide an asynchronous event-driven network application framework and tools for rapid development of maintainable high performance & high scalability protocol servers & clients.”

How to Reconnect Web Sockets in a Realtime Web App without Flooding the Server

Realtime web applications is has been a growing trend lately thanks to the technology behind it maturing in the major browsers. Over the next few years, it looks like more and more web apps are going to have realtime features in their UIs. As a developer, this is going to introduce some interesting challenges for us.

One such challenge is what should your app do when your backend becomes unreachable and your WebSocket gets closed. Generally, the best approach here is to gracefully turn off some features and get your application to start trying to reopen the WebSocket connection. Usually this results in some simple code that tries to create a new connection every few seconds:

https://gist.github.com/strife25/9310390

As a client developer, this logic makes a lot of sense and is simple to implement. However, there is a major problem here - every single client uses the same timing logic. This is bad news because of what will happen when your backend service finally comes back online; if everyone is polling at the same interval then they will all try to open a new connection to the backend at close to the same time. For example, say you have a large office (say a few thousand people) that has your web app running the entire day and their web socket connection is lost at the same time. Using the logic above, when the server is accessible again you will have a few thousand clients trying to create a WebSocket connection at exactly the same time. This will result in potentially flooding the server with requests and taking it down again.

A way to solve this problem is to use the Exponential Backoff algorithm. The benefit of this method is that it spreads out the reconnection attempts among the browsers to random intervals instead of everyone reconnecting to the server at the same time.

The algorithm works like so:

  1. For k attempts, generate a random interval of time between 0 and 2^k - 1.
  2. If you are able to reconnect, reset k to 1
  3. If reconnection fails, k increases by 1 and the process restarts at step 1.
  4. To truncate the max interval, when a certain number of attempts k has been reached, k stops increasing after each attempt.

An example of this algorithm in action can be found below in Javascript:

https://gist.github.com/strife25/9310539

The logic basically works like so:

  1. When the WebSocket connection is closed, create a random time interval between 0 and 1 second.
  2. If the connection is unable to re-open, increase the amount of reconnect tries by 1 and generate a new random interval. The interval this time will be a random value between 0 and 3 seconds.
  3. Continue steps 1 and 2 until that maximum possible interval reaches 30 seconds. At this point, all future intervals will be a random value between 0 and 30 seconds.
  4. Once connection has been re-established, reconnection attempts is reset to 1.

With realtime web apps becoming commonplace, maintaining your network connection to the backend services is an important technique to understand. Fortunately, this problem has already been solved for us and we can utilize a useful technique like Exponential Backoff to help us with this and not flood our servers with connection attempts.


If you’re interested in working on problems like this one and are located in Raleigh/Durham, NC or Indianapolis, IN, feel free to contact me (linus@johnryding.com) - we’re hiring at Interactive Intelligence!

Socket.IO の同時接続数とレイテンシの関係 (EC2 編)

Socket.IO でちょっとしたアクション系のゲームを作ることになり特にレイテンシがシビアになりそうなので調査。

テストした条件などはこんな感じ。

  • アプリは Node.js 0.10.15 + Socket.IO 0.9.16 + Express 3.3.4 で実装
  • ディストリビューションは Amazon Linux AMI 2013.3
  • m1.{xlarge,large,medium,small} の 4 種類のインスタンスタイプを使用
  • クライアントは専用の m1.xlarge のインスタンスから接続
  • 同時接続数は 1, 10, 50, 100, 500, 1000, 1500, 2000, 3000, 4000, 5000 で調査
  • 同時接続数の確認は HTTPServer#getConnections で取得できる値で実施
  • /etc/security/limit.conf で同時にオープンできるファイル数に 65535 を指定
  • トランスポートは WebSocket のみ
  • クラスタリング無し

以下のようなクライアントをぶら下げた状態で、100 ステップの平均レイテンシを計測。コネクション確立後、ping, pong でループを作ってストレスを与え続ける (緑色の枠)

レイテンシの計測は guille の latency-io を改造したもので確認。

計測結果 (レイテンシの単位はミリ秒)

グラフ

わかったこと

  • 当然だがインスタンスタイプに応じてレイテンシが変わる
  • CPU 使用率に余裕がある状況だと接続数が増えてもレイテンシは変わらない
  • 1500 を超えたあたりから性能が劣化し始める
    • m1.small は 500 を超えたあたりから性能劣化

最悪値は大体平均値の二倍。アプリの処理分もあるのとポーリングが無いので、実際の値は平均値の三倍ぐらいってとこだろうか。

CentOS에 socket.io 설치하기

1. NodeJS 설치

# vi/etc/yum.repos.d/SannisDev.repo

[home_SannisDev]
name=SannisDev's Home Project (CentOS_CentOS-5)
type=rpm-md
baseurl=http://download.opensuse.org/repositories/home:/SannisDev/CentOS_CentOS-5/
gpgcheck=1
gpgkey=http://download.opensuse.org/repositories/home:/SannisDev/CentOS_CentOS-5/repodata/repomd.xml.key
enabled=1

# yum install nodejs



2. npm 설치

# curl http://npmjs.org/install.sh | sh



3. socket.io 설치

# npm install socket.io



* 2, 3단계에서 tar 버전(1.15.x)이 낮으면 오류 발생할 수 있음. 이 때에는 1.2.6으로 업데이트 후 재시도

# wget http://ftp.gnu.org/gnu/tar/tar-1.26.tar.gz

# gzip -d tar-1.26.tar.gz 

# tar -xvf tar-1.26.tar.gz 

# FORCE_UNSAFE_CONFIGURE=1 ./configure —prefix=/usr \ —bindir=/bin —libexecdir=/usr/sbin 

# make 

# make install 

Running Websockets on Nodester!

Websockets are the latest craze and a natural fit for Node.JS.  Thanks to @DanBUK and @DavGlass, websockets are now supported on Nodester!

Deploying a websocket application to Nodester couldn’t be any easier.  We’ll use socket.io’s chat example as an example.  

All you need to make is two source code changes:

server.js
server.listen(8362);

chat.html
var socket = new io.Socket(null, {port: 80, rememberTransport: false}); 

Remember: The client side of the websocket always talks over HTTP port 80 on Nodester. The server side is the port that was assigned to you when you created your Nodester application.  You can always run the following CLI command to get the port addressed we assigned you (as the git repo and status):

nodester app info

Note: We actually just rolled out an enhancement where you no longer need to update your assigned port address.  We will automatically do it for you!

Now it’s time to deploy your hot new websocket-based Node.JS app on Nodester! Since Nodester applications are sandboxed, you will need to install your NPM module(s) with the following command:

nodester npm install socket.io

Node: You can install more than one module at once by adding a spaces between them such as nodester npm install socket.io express etc.

git push

That’s it!  If you need to restart your application for any reason, it’s as simple as:

nodester app restart

Now you’re ready to rock and roll with Nodester! Want to see this chat demo in action? Goto http://chat.nodester.com

youtube

HTML5/WebGL, 8 machines running Chrome, WebSockets and node.js/socket.io to say in sync.

Jetty は、100%JavaのJava Servletコンテナ・Webサーバである。WebSocketなどのプロトコルもサポートする。Jetty はオープンソースプロジェクトとして開発され、Apache 2.0 License でリリースされている。JBoss、Apache Geronimoといった他のプロジェクトでも利用されている。

単純で効率的な組み込みやすいWebサーバとなるよう意図して開発されている。サイズが小さいので、組み込み型 Java アプリケーションにWebサービスを提供するのに適している。

その一方で、Yahoo!のHadoopやGoogle App Engineといった大規模でスケーラビリティが重視されるサービスにおいても採用されている。

Sending Messages to a HTML5 WebSocket from Python

I’ve been spending a lot of time trying to send a message from a Python Socket to a HTML5 WebSocket. Well I found that if I send back the message I get from the WebSocket, the browser receives it without any problem, but if I want to send a custom string, it’s necessary to manipulate it before calling the send function. Let’s see the code:

data = s.recv(1024)
s.send(data)

The code above works perfectly, but it just return the same message. Now, let’s suppose that we want to return something different like a string saying what we’ve received:

s.send("received:" + data)

This works between Python Sockets, but not between a Python Socket and a HTML5 WebSocket because the last one never gets the message. So… the solution to this is to concatenate to the string message ‘\x00’ at the beginning and ‘\xff’ at the end, obtaining something like this:

msg = u"\x00received: %s\xff" % data.decode("utf-8", "ignore")
s.send(msg)

Now, your WebSocket will receive the message sent by the Python Socket.

Hope this will be useful for someone else.

Cheers.

The easiest way to add WebSockets to Django

TL;DR - I came up with a very simple solution to handle WebSockets in Django apps. You just install django-websocket-request, run a script and you have WebSockets for your Django app. The cool thing is that this solution makes Django believe its getting a (somewhat) normal HTTP request so you can reuse almost all of you application’s code. Plays nicely with Django REST Framework and with plain function-based views and class-based views. Check out the demo and it’s source code on GitHub.

Keep reading

processing webserver, notes

I started to revive an older version of a processing webserver (sHTTP) i wrote a while back which allows to control processing applications through a website based interface. First thing to get replaced was the server implementation with NanoHTTPD by Jarno Elonen and Konstantinos Togias. Works smooth and well, but I am giving my considerations another round of thought and will look into node.js and comet [1][2]. The web interfaces will be using jquery, ajax, socket.io to communicate with the processing application. The webserver will respond to requests by sending back static files stored inside a folder included in the application or will respond with on-the-fly-http-responses. Here i am looking at using json rather than xml to communicate between server and client.

What is the benefit of running a webserver within a processing application?

Control. It allows users to remotely connect to an app via a web browser. Clients here could be a desktop, laptop or any mobile device (iphone, ipad, android, etc.) which is connected to the same network.

Interface. The user interface design can be build with and make use of powerful javascript solutions like jquery. 

The downside of HTTP and AJAX is that it is quite costly and slow. Each request requires a round trip communication, whereby a request is sent for each update and the server responds accordingly.  Therefore using websockets would be the way to go. “Unlike traditional AJAX, in which each XMLHttpRequesconsists of a round trip which sends and then receives data from a remote server, a Web Socket sends and receives asynchronously on a single connection. This allows WebSockets to Reuse the same TCP stream, ’Push’ data to the browser and skip redundant HTTP headers.” sys-con.com

Good things to come with html5, the WebSocket API, “This specification defines an API that enables Web pages to use the WebSocket protocol for two-way communication with a remote host.” w3

Notes from the HTML5 live event in NYC

I missed the first half of the event, but below are a few takeaway points I captured from the other half:

1) HTML5 suite will be huge, but not immediately (at least not the complete suite). It is going to take a while for the complete spec to evolve and be supported by all browsers.
2) HTML5 is a huge umbrella spec, so some of its child specifications may/have get industry adoption earlier (like Websockets, etc.).
3) HTML5 will allow creation of real apps powered through the web. The kind of apps your are used to seeing on mobile and tablets.
4) Client-oriented architecture would be the next evolution. Although, it is early to comment on, but the role of application servers would be reduced significantly.
5) Websockets provide full duplex communication over HTTP, lend better to a star topology, and would significantly reduce the role load balancers and proxies would play in the future.
6) If done correctly (NIO, etc), Websockets provide very high levels of scalability, because of less payload, stateless applications (application server) and non-blocking threads.
7) Surprisingly Microsoft is playing a leading role in HTML5, and ie9 would support most of the HTML5 spec.

Side note: The talk by Dion Almaer and Ben Galbraith tocuhed on the importance of not selling apps for cheap. Geeks need to understand that electronic distribution of content is almost as expensive as physical content.

Apart from the Social Media thing, I did not really get Web 2.0. Hopefully HTML5 would be real thing.

Eventual Consistency in Real-time Web Apps

When building a real time web app, one has to figure out how to manage data that is coming from two data sources - one being the response from HTTP requests and the other being data sent over a web socket. In this environment, you need to deal with a couple of different situations:

  • Merging data that comes over the web socket into what’s already in memory.
  • Handling the case where data comes over the web socket while a request for the same piece of data was done over HTTP. For example, a PUT request to update a resource.
  • Getting the most up-to-date state of your resource after you have received an HTTP response but before you have subscribed to data received over the web socket.

These are all examples that I’ve dealt with myself in my current project and they all surround the same general problem:

How do you ensure that your local model is in sync with what’s stored on the backend?

Before I get into how we deal with this problem, I need to describe how we interact with our backend:

  • When working with web socket data, we refer to the received payloads as notifications.
  • In our client, we figure out which part of the app should respond to notifications by subscribing a function to a topic key name. When a notification is received, it includes this key and we use it to execute all functions that have registered to this key.(1)
  • In our application, data sent via notifications/over a web socket takes precedence over data received from an HTTP response.

The key to solve this problem comes down to utilizing two algorithms on your base model object:

  • Merging
  • Filling

These two techniques effectively do the same exact thing - given an existing model object and a new piece of data, combine the new piece of data into the existing object. However, there is a key difference here in what the two methods do during this process:

  • For a merge, new data should be added to the existing object. When encountering collisions between the existing object and new data, the new data’s value should override the existing data.
  • For a fill, new data should be added to the existing object. When encountering collisions between the existing object and new data, the existing data’s value will NOT be modified.

Looking at an example, lets take two objects:

https://gist.github.com/strife25/b99601536ffa85a7cdf1

When performing a merge function on myModel, the following would occur:

https://gist.github.com/strife25/6b7be0fc7db361fc998d

When performing a fill function on myModel, the following would occur:

https://gist.github.com/strife25/4d2a2538503ff0573ae2

So how do we utilize these methods in our UI to account for HTTP requests and Web Socket notifications? Well, we usually utilize these methods on page load when the javascript objects in our app are created. During this instantiation, we need to GET the data we want to display from the backend, subscribe for notifications, and respond to any web socket notifications. Here is the usual code we end up writing to do all this:

https://gist.github.com/strife25/ae41e2742231579ad4e7

In this example, a lot is going on. The way I usually think about is that there are two parallel tasks going on during page load:

  1. Load the initial data from the backend once the page is loaded.
  2. Subscribe to web socket notifications.

Looking at task one (loading the data from the backend), everything should look familiar. We do a GET HTTP request and create a new UserModel object from the response. However, for some reason, we need to account for when the user variable is already instantiated and perform a fill. This is where task two comes in.

In task two, we are performing a few steps:

  1. first we subscribe a function (onNotification) to a topic key ("users.{id}").
  2. Once we are successfully subscribed, perform another GET request via loadUser() to account for the situation where notifications were sent during the subscription process.
  3. When a notification is received, execute onNotification() to perform the merging of data from the web socket into the current UserModel may have already created.

The important step in task two is step 1 - subscribe to notifications. The moment that this step completes, the page is now allowed to respond to web socket notifications. This is a critical state because it may result in a situation where a notification is received over the web socket before the first GET request from loadUser() (task 1) has completed. In this situation, the notification’s data doesn’t have an issue - onNotification() executes, it sees that the user variable is undefined, so it creates a new instance of UserModel(). However, what should we do once the response from loadUser()'s GET request is received?

Looking at the done() function in loadUser() - the code will see that user already has a value, so it performs a fill(). The reason for using fill here is to ensure that we get eventual consistency in the app because it will not override the notification that was received. We do not perform a merge() function here because our app declares that notifications take precedence over HTTP responses for the same resource. This is because the data from the HTTP request may be stale by the time it is received after the notification. If we performed a merge here, that stale data would have overwritten the data received from the notification and our UI would become out of sync with the backend data. Performing a fill() will instead just add in any missing data attributes to the user value and not overwrite any existing data.

The last step of the subscription logic is step two of when we subscribe to notifications:

2) Once we are successfully subscribed, perform another GET request via loadUser() to account for the situation where notifications were sent during the subscription process.

This second request is used to handle the situation where the first call to loadUser() has completed and notification data was sent from our backend but before we have finished subscribing onNotification() to respond to the notification. What this means is that the backend data has been updated after the first GET request has completed, but the update message was lost. To account for this situation, we need to perform a second call to loadUser() to ensure that we have the most up-to-date state of the user model from the backend. Fortunately, if any notifications are sent during this second request, onNotification will respond accordingly and those new values will not get overwritten when the second HTTP response is received.

After all is said and done, once the data is loaded and the page has subscribed to user notifications, our user variable will eventually become consistent with the state stored on the backend of our web app.

In summary, when dealing with eventual consistency in your web apps, here are the techniques I have seen success with:

  • Utilize/implement merge and fill algorithms on your model objects to handle the updating of existing model data in your app.
  • Treat data received from multiple data sources (web sockets and HTTP requests in this case) as input methods to your page that run in parallel.
  • Declare that one of these data inputs take precedence over the others. When data is received from the higher priority source, perform a merge to combine with the existing data. All other data input sources should instead perform a fill for new data.

Notes

  1. Underneath the covers, we are essentially using Publish-Subscribe.
  2. Many thanks goes to Matt Cheely for teaching me these techniques.