Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Socket.io simple chat application has unstable connectivity on IISExpress #53

Closed
simtan opened this Issue Sep 28, 2011 · 3 comments

Comments

Projects
None yet
2 participants

simtan commented Sep 28, 2011

I was trying out socket.io with node on IISExpress inside WebMatrix and I think I’ve come across a reproducible bug.

With an app.js like the following:

var express = require('express'), path = require('path'), io = require('socket.io');

var app = module.exports = express.createServer().configure(function() {
    // Root folder for views
    this.set('views', path.join(__dirname, "views"));

    // Default filename extension and corresponding view engine
    this.set('view engine', 'ejs.html');
    this.register('ejs.html', require('ejs'));

    // Middleware to process POST parameters in requests
    this.use(express.bodyParser());
});

app.get('/', function (req, res) {
    res.render('index', { chatlog: [] });
});

// Use socket.io, an enhanced implementation of Websockets for all browsers

io = io.listen(app);

io.configure(function () { 
  io.set("transports", ["xhr-polling"]); 
  io.set("polling duration", 10); 
});

app.listen(process.env.PORT || 8080);

io.sockets.on('connection', function (socket) {
  socket.emit('message', 'Welcome to the chat room!');

  socket.on('incoming', function (data) {
    socket.emit('message', data);
    socket.broadcast.emit('message', data);
  });
});

Run it with node.exe – the chat room functionality should work fine, with multiple browsers and everything.

Open the site with WebMatrix (that should already be configured for Node support) and launch the site. IISExpress will occasionally return messages correctly, but will often lag or sometimes even stop responding.

simtan commented Oct 11, 2011

The code above is missing the view; here is /views/layout.ejs.html :

<!DOCTYPE html>
<html>
    <head>
        <link rel="Stylesheet" href="/css/site.css" />
        <title>Chat Room<% if (locals.pageTitle) { %> :: <%= locals.pageTitle %><% } %></title>
    </head>
    <body>
        <div id="header">          
            <h1>Chat Room</h1>
            <div id="headerLinks">
                <a href="/">Room</a>
                <a href="/about">About</a>
            </div>  
        </div>
        <%- body %>
    </body>
</html>

And /views/index.ejs.html:

<script src="/socket.io/socket.io.js"></script>

<form class="entry" action="/send" method="post" onsubmit="return sendMessage();">

    <div id="chat">
        <% for (var i = 0; i < chatlog.length; i++) { %>
            <div class="message">
                <%= chatlog[i] %>
            </div>
        <% } %>
    </div>

    <h3>Enter a message:</h3>
    <input type="hidden" name="chatlog" value="<%= chatlog.join("\r\n") %>" />
    <input type="text" id="message" name="message" />
    <button id="submitMessage" type="submit">Send</button>
</form>



<script>
    // Connect to the server and set up listening for new messages
    var socket = io.connect('/');
    socket.on('message', function (data) {
        showMessage(data);
    });
    socket.on('disconnect', function() {
        showMessage("You have been disconnected.");
    });

    // Identify input text box and set focus to it
    var messageBox = document.getElementById('message');
    setFocus();

    /*
     * Create and inject message DOM object into chat box
     */
    function showMessage(message) {
        var newMessage = document.createElement('div');
        newMessage.setAttribute('class', 'message');
        newMessage.innerHTML = message;
        document.getElementById('chat').appendChild(newMessage);
    }

    /* Send message to server */
    function sendMessage() {
        if (messageBox.value) socket.emit('incoming', messageBox.value);
        messageBox.value = '';
        setFocus();
        return false;
    }

    /* Set focus to the input text box */
    function setFocus() {
        messageBox.focus();
    }
</script>

simtan commented Oct 12, 2011

I edited the repro code for app.js to include a snippet from here:
http://devcenter.heroku.com/articles/using-socket-io-with-node-js-on-heroku

I was hopeful that it might solve the problem, but IISNode on IIS Express (for WebMatrix) still behaves the same way when running this app.

Owner

tjanczuk commented Oct 18, 2011

Fixed by 0bc9f9b. This was a complex race condition in request finalization code path.

Please note that iisnode does not support websocket transport, but using socket.io is still possible with other HTTP-based transports like HTTP long polling:

io.configure(function() {
    io.set('transports', ['xhr-polling']);
});

@tjanczuk tjanczuk closed this Oct 18, 2011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment