socket.io使用

Socket.io服务端对象

const app = require('express')();
const server = require('http').Server(app);
const io = require('socket.io')(server); //服务端的Socket.io对象

Socket.io客户端对象

  <!-- 需要加载socket.io客户端第三方库 -->
        <script type="text/javascript" src="/socket.io/socket.io.js"></script>
        <script>
            const socket = io(); //Socket.io客户端对象
        </script>
  • socket.io事件

    • socket.io服务器的系统事件
      1. io.on(‘connection’, callback): 有新Socket连接建立时
      2. socket.on(‘message’, callback): 当有socket..send()方法发送完信息后触发
      3. socket.on(‘disconnect’, callback): 当连接断开时触发
    • 客户端的系统事件
      1. socket.io.on(‘open’, callback): 当socket客户端开启与服务器的新连接时触发
      2. socket.io.on(‘connect’, callback):当socket客户端连接到服务器后触发
      3. socket.io.on(‘connect_timeout’, callback):当socket客户端与服务器连接超时后触发
      4. socket.io.on(‘connec_errort’, callback):当socket客户端连接服务器失败时触发
      5. socket.io.on(‘connec_attemptt’, callback):当socket客户端尝试重新连接到服务器后触发
      6. socket.io.on(‘reconnect’, callback):当socket客户端重新连接到服务器后触发
      7. socket.io.on(‘reconnect_error’, callback):当socket客户端重新连接服务器失败后触发
      8. socket.io.on(‘reconnect_fail’, callback):当socket客户端重新连接到服务器失败后触发
      9. socket.io.on(‘close’, callback):当socket客户端关闭与服务器的连接后触发
  • 事件触发

    • 服务端触发
    • 客户端触发
/*服务端*/
  io.on('connection', function (socket) {
       socket.emit('customEvent', message);
    });
<!--客户端-->
<script>
var socket = io();
socket.emit('customEvent', mesaage);
</script>
  • 事件处理
/*服务端*/
io.on('connection', function (socket) {
    socket.on('customEvent', (message) => {
            /*逻辑代码*/
    }
});

//通过broadcast属性可以给处理当前连接外的所有连接的socket客户端发送事件:
io.on('connection',(socket)=>{
    socket.broadcast.emit('customEvent', meassage);
});
<!--客户端-->
<script>
    var socket =io();
    socket.on('eventName',(message)=>{
         /逻辑代码*/
    });
</script>
  • socket.io命名空间:对socker连接进行划分命名空间,可以对不同的socket的连接分类管理,而且不需要新建socket服务器实例.
//服务端命名空间
io.of('/someNameSpace').on('connection', (socket)=>{
    socket.on('customEvent', (message)=>{
        /*逻辑代码*/
    });
});
<!--客户端命名空间-->
<script>
    var someSocket = io('/someNameSpace');
    someSocket.on('customEvent', (message)=>{
        /*逻辑代码*/
    });
</script>
  • Socket.io的房间:房间功能动态的对已连接的socket进行分组.socket连接可以加入和离开房间
io.on('connection', (socket)=>{  //加入房间
    socket.on('join', (roomData)=>{
        socket.join(roomData.roomName);
    });
        socket.on('leave', (roomData)=>{  //离开房间
        socket.leave(roomData.roomName);
    });
});

//房间中触发事件
io.on('connection', (socket)=>{   //对房间所有socket连接
    io.in('someRoom').emit('customEvent', message);
});

//对房间内除了当前连接外的socket触发事件
io.on('connection', (socket)=>{   //对房间所有socket连接
    io.broadcast.to('someRoom').emit('customEvent', message);
});
  • 服务端:使用了express框架搭建,socket.io将借住express服务来实现用户验证,同步会话;
express.js

/*socket.io实时通讯的使用*/
const socketio = require('socket.io'),
    http = require('http'),
    MongoStore = require('connect-mongo')(session); //当作会话数据储存


module.exports = function() {
    var server = http.createServer(app);  //使用新的server替换以前的express应用对象
    var io = socketio.listen(server);   //将soket.io服务附加给server
//创建MonggoStore的实例,并传入了Mongoose的连接对象
    var mongoStore = new MongoStore({
        url: config.db
    });

    app.use(session({    //配置session,存储到mongo数据库中
        saveUninitialized: false, //是否自动保存未初始化的会话,建议false
        resave: false,      //是否每次都重新保存会话,建议false
        secret: config.sessionSecret,
        store: mongoStore,
        cookie: {
            maxAge: config.minute
        }
    }));
    require('./socketio')(server, io, mongoStore); //为server和io,配置处理客户端信息的处理
}


socketio.js

'use strict';

var config = require('./config'),
    cookieParser = require('cookie-parser'),
    passport = require('passport');

module.exports = function (server, io, mongoStore) {
    io.use(function (socket, next) {  
        //使用cookieParser来解析握手请求中的cookie,并且获取对应express中的sessionId
        cookieParser(config.sessionSecret)(socket.request, {}, function (err) {
            var sessionId = socket.request.signedCookies['connect.sid'];

            //使用mongoStore检索会话信息
            mongoStore.get(sessionId, function (err, session) {
                socket.request.session = session;

                //一旦检索到就用passport.initialize()和passport.session()中间件根据会话
                //信息来填充会话的user对象
                passport.initialize()(socket.request, {}, function () {
                    passport.session()(socket.request, {}, function () {
                        if(socket.request.user) {
                            next(null, true);
                        } else {
                            next(new Error('User is not authenticated'), false);
                        }
                      });
                });
            });
        });
    });

    io.on('connection', function (socket) { //监听新连接,有的话调用处理函数
        require('../app/controllers/chat.server.controller')(io, socket);
    });
};


chat.server.controller.js

'use strict';
module.exports = function (io, socket) {
    io.emit('chatMessage', {    //通过io对象向所有监听'chatMessage'事件的客户端发送消息
        type: 'status',
        text: 'connencted',
        created: Date.now(),
        username: socket.request.user.username
    });


    socket.on('chatMessage', (message) => { //监听socket客户端'chatMeaasge'事件
        message.type = 'message';
        message.created = Date.now();
        message.username = socket.request.user.username;

        io.emit('chatMessage', message);
    });


    socket.on('disconnect', () => {    //监听socket客户端与服务器断开建立的事件,并且触发回调
        io.emit('chatMessage', {
            type: 'status',
            text: 'disconnected',
            created: Date.now(),
            username: socket.request.user.username
        });
    });
};
  • 客户端:使用的是Angular1.x的前端框架
chat.client.service.js

angular.module('chat').service('Socket', ['Authentication', '$location', '$timeout', 
    function (Authentication, $location, $timeout) {
        if(Authentication.user) {   //判断是否有用户登陆
            this.socket = io();
        } else {
            $location.path('/');
        }

        this.on = function (eventName, callback) {  //监听evetName事件
            if(this.socket) {           //判断io()是否实例化;
                this.socket.on(eventName, function (data) {
                    $timeout(function () {  //socket客户端是第三方库,需要用$timeout触发Angular的绑定操作
                        callback(data);
                    });
                });
            }
        }


        this.emit = function (eventName, data) {   //触发eventName事件
            if(this.socket) {
                this.socket.emit(eventName, data);
            }
        }


        this.removeListener = function (eventName) {    // 取消eventName事件监听
            if(this.socket) {
                this.socket.emit(eventName);
            }
        }
    }]);

chat.client.controller.js

angular.module('chat')
    .controller('ChatController', ['$scope', 'Socket',
    function ($scope, Socket) {
        var self = this;
        $scope.messages = [];
        Socket.on('chatMessage', function (message) {
            $scope.messages.push(message);
        });

        $scope.sendMessage = function () {
            console.log(self.messageText);
            var message = {
                text: self.messageText,
            }

            Socket.emit('chatMessage', message);
            self.messageText = '';
        }

        $scope.destory = function () {  //离开聊天室
            Socket.removeListener('chatMessage');
        }
}]);

index.html
 <!-- 需要加载socket.io客户端第三方库 -->
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值