2

I'm going to add some websockets capabilities in my Angular/nodejs application using socket.io.

The final purpose is to keep on server a "live" array of unavailable for writing documents (because someone else is editing them). But I started from the socket.io chat example and I've got stuck very soon. I'm sure I'm missing something trivial here. $scope.sendMessage() doesn't emits anything..

FRONT

html

 <input type="text" class="form-control" placeholder="message" name="message" ng-model="message"> <button type="button" ng-click="sendMessage()"> sendMessage </button>

socket.io is wrapped in a service

app.factory('socket', function ($rootScope) {
    var socket = io.connect();
    return {
        on: function (eventName, callback) {
            socket.on(eventName, function () {
                var args = arguments;
                $rootScope.$apply(function () {
                    callback.apply(socket, args);
                });
            });
        },
        emit: function (eventName, data, callback) {
            socket.emit(eventName, data, function () {
                var args = arguments;
                $rootScope.$apply(function () {
                    if (callback) {
                        callback.apply(socket, args);
                    }
                });
            })
        }
    };
});

controller

$scope.messages=[]
socket.on('init', function (data) {
});
socket.on('send:message', function (message) {
    console.log("send:message")
    $scope.messages.push(message);
});
$scope.sendMessage = function () {
    console.log("send:message")
    socket.emit('send:message',$scope.message);
    $scope.messages.push($scope.message);
};

SERVER

var http = require('http');
var server = http.createServer(app);
var io = require('socket.io')(server);
io.on('connection', function (socket) {
  console.log('a user connected');
  socket.on('disconnect', function () {
    console.log('user disconnected');
  });

  socket.on('send:message', function (message) {
    console.log('send:message:'+message);
    socket.broadcast.emit('send:message', {
      text:message
    });
  });
});
9
  • Surely the server should put a handler on "receivemessage", because it will be receiving it, not sending it? Commented Oct 23, 2016 at 0:38
  • Well reading this socket.io/get-started/chat at "Emitting events" I'm not sure what's wrong with my code Commented Oct 23, 2016 at 0:49
  • ok, makes sense. DOes the connection work ok? At what point does it stop working? Are you getting browser console errors? express console errors? Commented Oct 23, 2016 at 1:10
  • I see on server console "a user connected", but nothing else. I'm not sure if the problem is the emit(send:message) on the client or the handler socket.on('send:message') on the server. No error at all. Commented Oct 23, 2016 at 1:25
  • Does it write to the browser console as you send? Commented Oct 23, 2016 at 1:30

2 Answers 2

1

I've created a little app using this stack. Check out my project here. I've used this wrapper around socket-io made for AngularJs and found it to be quite easy to use!

In essence, in my project I have the following:

NodeJs Server code (entry point):

class Server {
    constructor() {
        this.express = require('express');
        this.redis = require('redis');
        this.client = this.redis.createClient(); //creates a new client
        this.app = this.express();
        this.server = require('http').Server(this.app);
        this.io = require('socket.io').listen(this.server);
        this.app.use('/node_modules', this.express.static(__dirname + '/node_modules'));
        this.app.use('/static', this.express.static(__dirname + '/static'));
        this.app.get('/', (req, res) => {
            res.sendFile(__dirname+'/index.html');
        });

        this.server.listen(8081, '0.0.0.0', () => { // Listens to port 80
            console.log('Listening on ' + this.server.address().port);
        });
        this.setup();
    }

    setup() {
        this.io.on("connection", (socket) => {
            this.socket = socket;
            this.centralServer();
        });
    }
    ...
    ...
}

And then, in index.html, I've loaded the JS for the required libraries:

<html lang="en">
<head>
   ...
   ...
    <script src="/node_modules/socket.io-client/dist/socket.io.js" type="text/javascript"></script>
    <script src="/node_modules/redis/index.js" type="text/javascript"></script>
    <script src="/node_modules/angular-socket-io/socket.min.js" type="text/javascript"></script>
    <script src="/static/js/main.js" type="text/javascript"></script>
    ...
    ...
</head>
<body ng-app="app">
    <div ng-include='"static/views/<mainDOM>.html"'></div>
</body>

And finally, in my Angular app, I've got the following:

var app = angular.module("app", ['btford.socket-io']);
app.controller('myGame', ['$scope', 'socketFactory', function($scope, socketFactory) {
    class Player {
        constructor() {
            this.dom          = $scope;
            this.dom.Room     = {};
            this.socket       = socketFactory();
            this.dom.roomExists   = false;
            this.setup();
        }
    ...
    ...
    }
    $scope.player = new Player();
}

I think I've done a good job in this project of providing a minimal example of AngularJS + Socket-io.

Sign up to request clarification or add additional context in comments.

Comments

0

This is indeed a complex problem you have created for yourself. I would do it by creating a backend service (over http) to manage the locking.

When a user asks to edit a document, they are granted a lock, and and can enter the edit page. When they save it, the lock is released. If another user asks to edit, the status return tells them it is locked, and they are shown an error dialog.

You may need to have some kind of timeout on the locks in case the user closes the browser, or forgets to save. Managing this over socket connections will be a lot of work, and difficult to debug. keeping everything as simple http requests will be much easier.

4 Comments

It's just matter of handle the right events, don't you think? I like the idea of websocket (actually I'm trying this way for fun..I would make a rest resource with 'ping' interval in no-time, but where's the fun? :) )
I even start to think there is no reason to handle so much events. The clients should emit doc:lock and doc:unlock and handle doc:list. That's all.
If you are up for a challenge that's fine, it is quite possible to make this work properly with some determined effort
I spent about 1 hour and I started to think it's not that piece of cake I thought :) The problem is angular routing.. also there are very few examples in angular/socket.io around the web..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.