简体   繁体   中英

Angular 1.6.9 and socket.io chat application

The following code I have developed so far for a chat application using Angular and Socket.io. The crucial part that I can't seem to fix is the "nickWrap". It consists of a message 'Enter Nickname', an input text box and a submit button. The nickname is passed to the server where it checks in an array if the nickname is already present. If not then it should give back a success, then I should disable the form and show another div content. But it seems that after I get back a success message, I have to type something in the input textbox again and only then it gets disabled. Also, the list of users online after this form is disabled is not always correctly shown in select using ng-repeat. There is always an empty space. Plus when another user connects, then the existing user can't dynamically see new user in the select list, while the new user can see old users. If any one user disconnects, then the select list of other user's client doesn't dynamically update the list either. I am pretty new to Angular, nodejs, socket.io and all of this

The Client Code is:

<!doctype html>
<html>
    <head>
        <title>chat</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>

        <script src="/socket.io/socket.io.js"></script>
        </script>
        <!--<script src="app.js"></script>-->
        <script>
            var app = angular.module("myApp", []);
            var socket = io();
            var storedName;
            app.controller("myCtrl", function($scope) {
                $scope.ok=false;
                $scope.chatOK=false;
                $scope.myFunc = function () {
                    socket.emit('new user',$scope.nickname,function(data){
                        if(data){
                            alert('You picked good nickname');
                            $scope.ok=true;
                        }
                        else
                        {
                            alert('Pick a different Nickname');
                            $scope.ok=false;
                        }
                    });
                    //storedName=$scope.nickname;
                    $scope.nickname="";
                }
                $scope.sendRequest=function(){
                    alert('Chat Request sent to '+$scope.selector+' !');
                    $scope.chatOK=true;
                }
                socket.on('usernames',function(data){
                    $scope.names=data;
                    alert($scope.names);
                });
            });
        </script>
    </head>
    <body ng-app="myApp" ng-controller="myCtrl">
        <div id="nickWrap">
            <span>Enter NickName:</span>
            <div>
                <form ng-submit="myFunc()">
                    <input type="text" placeholder="random nickname" ng-model="nickname" ng-disabled="ok">
                    <input type="submit" ng-disabled="ok">
                </form>
            </div>
            <p>
            <div id="chatWrap" ng-show="ok">
                <select name="sometext" size="20" style="width:200px" ng-model="selector">
                    <option ng-repeat="namelist in names">{{namelist}}</option>
                </select><br/>
                <Strong>LIST OF ONLINE USERS</Strong>
            </div>
        </div>
        <div id="requestWrap" ng-show="selector">
            <form ng-submit="sendRequest()">
                <input type="submit" value="Send Chat Request to {{selector}}"/>
            </form>
        </div>
        <div id="messageWrap" ng-show="chatOK">
            MESSAGES WILL APPEAR HERE SOON!!!!!!
        </div>
    </body>
</html>

The server code is:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var nicknames=[];

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});
app.post('/log', function(req, res){
  console.log('someone connected');
});

io.on('connection', function(socket){
    console.log('a user '+socket.id+' connected');
    socket.on('disconnect', function(){
      console.log('user '+socket.id+' disconnected');
      //if(!socket.nickname) return;
      nicknames.splice(nicknames.indexOf(socket.nickname),1);
      socket.emit('usernames',nicknames);
      //updateNames();
    });
    socket.on('chat message', function(msg){
      console.log('message from user '+socket.id+' : ' + msg);
    });
    socket.on('new user',function(data, callback){
      console.log(data);
      if(nicknames.indexOf(data)!=-1){
        callback(false);
      }
      else{
        callback(true);
        socket.nickname=data;
        nicknames.push(data);
        //updateNames();
        socket.emit('usernames',nicknames);
      }
    });
    socket.on('chat message', function(msg){
      io.emit('chat message', msg);
    });
    //function updateNames(){
      //socket.emit('usernames',nicknames);
    //}
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

Your first 2 problems (input disabled and ng-repeat) are linked.

In angularJS, when you call a service like socket.emit, you go out of angular's context and the $scope is not updated.

After you set your variables you need to force a call to $scope.$apply()

socket.emit('new user',$scope.nickname,function(data){
  if(data){
    alert('You picked good nickname');
    $scope.ok=true;
  } else {
    alert('Pick a different Nickname');
    $scope.ok=false;
  }
  $scope.$apply();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM