
Security News
Another Round of TEA Protocol Spam Floods npm, But It’s Not a Worm
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.
browserchannel
Advanced tools
tldr; Its like socket.io, but it scales better and it has fewer bugs. It just does long polling. It also doesn't support websockets and doesn't support cross-domain requests out of the box.
Note: Websocket support is now reasonably universal. Strongly consider using raw websockets for new projects.
BrowserChannel is google's version of socket.io from when they first put chat in gmail. Unlike socket.io, browserchannel guarantees:
node-browserchannel:
# npm install browserchannel
Browserchannel is implemented as connect middleware. Here's an echo server:
var browserChannel = require('browserchannel').server;
var connect = require('connect');
var server = connect(
connect.static("#{__dirname}/public"),
browserChannel(function(session) {
console.log('New session: ' + session.id +
' from ' + session.address +
' with cookies ' + session.headers.cookie);
session.on('message', function(data) {
console.log(session.id + ' sent ' + JSON.stringify(data));
session.send(data);
});
session.on('close', function(reason) {
console.log(session.id + ' disconnected (' + reason + ')');
});
// This tells the session to disconnect and don't reconnect
//session.stop();
// This kills the session.
//session.close();
})
);
server.listen(4444);
console.log('Echo server listening on localhost:4444');
The client emulates the websocket API. Here is a simple client:
var BCSocket = require('browserchannel').BCSocket;
var socket = new BCSocket('http://localhost:4321/channel');
socket.onopen = function() {
socket.send({hi:'there'});
};
socket.onmessage = function(message) {
console.log('got message', message);
};
// later...
socket.close()
... Or from a website:
<html><head>
<script src='/channel/bcsocket.js'></script>
<script>
socket = new BCSocket('/channel');
socket.onopen = function() {
socket.send({hi:'there'});
socket.close();
};
socket.onmessage = function(message) {
// ...
};
</script>
You can also ask the client to automatically reconnect whenever its been disconnected. - Which is super useful.
var BCSocket = require('browserchannel').BCSocket;
socket = new BCSocket('http://localhost:4321/channel', reconnect:true);
socket.onopen = function() {
socket.send("I just connected!");
};
{x:undefined} turns in to {x:null} not {}.The server is created as connect / express middleware. You create the middleware by calling
var browserChannel = require('browserchannel').server;
var middleware = browserChannel(options, function(session) {
...
});
// Express
app.use(middleware);
The options object is optional. The following server options are supported:
hostPrefixes: ['a', 'b', 'c'] to make clients send requests to
a.example.com, b.example.com and c.example.com."/channel"). Think of the base URL as a URL passed into app.use(url, middleware).Access-Control-Allow-Origin header. This allows you to
specify a domain which is allowed to access the browserchannel server. See
mozilla documentation
for more information. You can set this to '*' to allow your server to be
accessed from clients on any domain, but this may open up security
vulnerabilities in your application as malicious sites could get users to
connect to your server and send arbitrary messages.Access-Control-Allow-Credentials header in responses. This allows
cross-domain requests to send their cookies. You cannot do this if you set
cors:'*'. To make this work you must also add the {crossDomainXhr:true}
option in the client. See mozilla
documentation
for more information. Setting this is equivalent to setting
headers:{'Access-Control-Allow-Credentials':true}.Note that by default, CORS support is disabled. This follows the lead of browsers. Be very careful when enabling CORS & CORS credentials. You should explicitly whitelist sites from which your users will connect.
Setting hostPrefixes in production is important - if you don't enable host prefixes, browserchannel will stop working for a user once they have more than a couple of tabs open. Set DNS rules to make the extra prefixes all point to the same server / cluster.
Whenever a client connects, your middleware's method is called with the new session. The session is a nodejs event emitter with the following properties:
'init', 'ok' and
'closed'. When the state is changed, the client will emit a state changed
event with the new state and old state as event parameters.You can send messages to the client using client.send(data, callback). The
data parameter will be automatically JSON.stringified. If specified, the
callback will be called once the message has been acknowledged by the client.
Note: If you wrap a browserchannel connection in a nodejs stream, don't use the callback. Node streams will only allow one message to be in flight at a time. As a result, you'll get much lower message throughput than you otherwise should.
Receive messages through the message event.
session.on('message', function(data) {
// ...
});
The message will be a javascript object if you sent a javascript object using the client API.
Browserchannel has two different methods for closing client connections, session.stop and session.close. Both methods disconnect the client. The difference is that stop also tells the client not to reconnect. You should use close when a recoverable server error occurs, and stop when the client is in an unrecoverable invalid state.
For example, if an exception occurs handling a message from a client, you may want to call close() to force the client to reconnect. On the other hand, if a browser is trying to connect using an old version of your app, you should call stop(). In the browser, you can handle the stop message with a notice to refresh the browser tab.
The client is an event emitter. It fires the following events:
For the most part, the client API is identical to websockets.
var socket = new BCSocket(hostname, opts);
opts is optional, and if it exists it should be an object which can contain the following properties:
session.appVersiona by default. Your application may override the
variable name if there is a query string conflict.There are a couple of differences from the websocket API:
send() using JSON objects instead of
mere strings. JSON serialization is handled by the library, and works in all
browsers.socket.onconnecting = function() {...} to send any messages which need to be
sent as the session is established. This will be called both when the socket is
first established and when the session reconnects.The client uses google's closure library & compiler. There's a couple small bugs that google still hasn't fixed in their library (and probably never will), so I have a patch file kicking around.
Rebuilding the client library is annoying, so I keep an up to date compiled copy in dist/.
Download the closure library as a sibling of this repository
cd ..
git clone https://code.google.com/p/closure-library/
git checkout -q df47692b1bacd494548a3b00b150d9f6a428d58a
cd closure-library
Download the closure compiler
curl http://dl.google.com/closure-compiler/compiler-latest.tar.gz > compiler-latest.tar.gz
tar -xvf compiler-latest.tar.gz
mv compiler-latest/compiler.jar .
Patch the library
cd closure/
patch -p0 < ../../node-browserchannel/closure-*.patch
Build
cd ../../node-browserchannel
make
Building this project with Java ~1.6 will fail, and may even fail silently.
Until the bug introduced in closure-library#83c6a0b9
is resolved upstream, use closure-library#df47692
Licensed under the standard MIT license:
Copyright 2011 Joseph Gentle.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
FAQs
Google BrowserChannel server for NodeJS
We found that browserchannel demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.

Security News
PyPI adds Trusted Publishing support for GitLab Self-Managed as adoption reaches 25% of uploads

Research
/Security News
A malicious Chrome extension posing as an Ethereum wallet steals seed phrases by encoding them into Sui transactions, enabling full wallet takeover.