Socket.io for Unity3d Authorization

本节我们给 Socket.io加上 安全套。 大家都知道 Socket.io 要是不做验证的话,大家都可以访问到。在这实际的生产环境中是 绝对不容许的。 我们就用Socket.IO 自带的 Authorization 给 Socket.IO 做一个 安全效验!我们先上图

现在代码中添加对   require('socketio-auth') 的引用。


运行出现下图的报错了 是没有添加 Socket-auth 库


第一步先把  socketio-auth 下载下来 然后 就可以 跑起来了。

主要参考地址:https://cnodejs.org/topic/55a66ddd5a4b4a86539c2fe6  (有可能是版本原因,没有成功)

后来参照 GitHub  https://github.com/facundoolano/socketio-auth

才完成需求

服务器端:

/*!
 * express
 * Copyright(c) 2009-2013 TJ Holowaychuk
 * Copyright(c) 2013 Roman Shtylman
 * Copyright(c) 2014-2015 Douglas Christopher Wilson
 * MIT Licensed
 */
'use strict';
module.exports = require('./lib/express');
var io = require('socket.io')({
    transports: ['websocket'],
});

require('socketio-auth')(io, {
    authenticate: authenticate,
    postAuthenticate: postAuthenticate,
    disconnect: disconnect,
    timeout: 10000
});

io.attach(4567);
console.log('Server Start....');



var socketArray = {};//Socket ����

io.on('connection', function (socket) {
    console.log('Client Contect. SocketID:'+socket.id);
    //socket.emit('SocketProtocol.Info', { hi: 'Hello,world' });
    socket.emit('SocketProtocol.Info', "ConnectServer Scuess! :"+socket.id);
    socket.on('SocketProtocol.Login', function (data) {
        console.log(data);

        //var content = JSON.parse(data);
        socket.nickName =  data.nickName;
        socket.guid      = data.guid;
        //
        if( !socketArray.hasOwnProperty(socket.guid) )
        {
            socketArray[socket.guid] = data;
        }
        //
        //console.log(socketArray);
        var chatContent={};
        chatContent.nickName        =  socket.nickName;
        chatContent.chatMessage     = "Login Scuess";

        socket.emit('SocketProtocol.Login',chatContent);


    });

    socket.on('SocketProtocol.Chat', function (data) {
        //console.log("SocketProtocol.Chat:"+data);

        var chatContent ={};
        chatContent.nickName      = socket.nickName;
        chatContent.chatMessage  = data.chatMessage;

        console.log("chatContent.toJSON():"+JSON.stringify(chatContent));
        io.sockets.emit('SocketProtocol.Chat',chatContent);//All SocketUsers
        //socket.broadcast.emit(data);//All SocketUsers But Self
    });

    socket.on('disconnect', function () {
        console.log("disconnect");
        if(  socketArray.hasOwnProperty(socket.guid) )
        {
           delete socketArray[socket.guid];
           console.log("disconnect Delete:"+socket.guid);
        }
        console.log("Inline Count:"+countProperties(socketArray));
    });

});

function countProperties (obj) {
    var count = 0;
    for (var property in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, property)) {
            count++;
        }
    }
    return count;
}

this.size = function () {
    var count = 0;
    for (var prop in items) {
        if (items.hasOwnProperty(prop)) {
            ++count;
        }
    }
    return count;
};

function authenticate(socket, data, callback) {

    console.log("authenticate");

    var username = data.username;
    var password = data.password;



    console.log("authenticate:username:  "+username);
    console.log("authenticate:password:  "+password);

    //db.findUser('User', {username:username}, function(err, user) {
    //    if (err || !user)
    //    {
    //        return callback(new Error("User not found"));
    //    }
    //    return callback(null, user.password == password);
    //});

     //两种回传方式 例子中是通过数据库的方式判断的。在这里 我们就模拟了 验证成功和失败两种
     return callback(null,"OK! Scuess!");

    //return callback(new Error("Fail"));

}

function postAuthenticate(socket, data) {
    //var username = data.username;
    //
    //db.findUser('User', {username:username}, function(err, user) {
    //    socket.client.user = user;
    //});

    console.log("postAuthenticate");

    var user = {};
    user.username  = data.username;
    user.password  = data.password;

    socket.client.user = user;
}

function disconnect(socket) {
    console.log(socket.id + ' disconnected');
}

function ShowObjectProty(date) {
    for (var item in date){
        console.log(date[item]);
    }
}


客户端

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SocketIO;
using System;
 
using LitJson;

public class SocketController : MonoBehaviour {
 

    SocketIOComponent socketIO;
    private bool    login;
    private string chatMessage  = "";
    private string chatContent  = "";
    private string nickName     = "";
    private Guid guid = Guid.NewGuid();


    // Use this for initialization
    void Start ()
    {

        GameObject go = GameObject.Find("SocketIO");
        if (go == null)
        {
            go       = new GameObject("SocketIO");
            socketIO = go.AddComponent<SocketIOComponent>();
        }
        else
        {
            socketIO = go.GetComponent<SocketIOComponent>();
            if (socketIO == null)
            {
                socketIO = go.AddComponent<SocketIOComponent>();
            }
        }

        socketIO.url = "ws://192.168.0.170:4567/socket.io/?EIO=3&transport=websocket";

        socketIO.Connect();
        socketIO.socket.OnOpen += (object sender, EventArgs e) =>
        {
           Dictionary<string, string> data = new Dictionary<string, string>();
           data["username"] = "John";
           data["password"] = "secret";
           socketIO.Emit("authentication", new JSONObject(data));
        };


        OnAddEvemt();
    }



    private void OnGUI()
    {

        if (!login)
        {
            Rect rect = new Rect(Screen.width / 3, Screen.height / 3, Screen.width / 3, Screen.height / 2);
            GUI.Box(rect, "" );


            GUI.Label(new Rect(rect.x + Screen.width / 60, rect.y + Screen.height / 9, rect.width - Screen.width / 15, Screen.height / 15),"请输入昵称:");
  
            nickName =  GUI.TextField(new Rect(rect.x + Screen.width / 10, rect.y+ Screen.height / 10, rect.width- Screen.width / 5, Screen.height / 15), nickName);

            if( GUI.Button(new Rect(rect.x + Screen.width / 30, rect.y + Screen.height/4, rect.width - Screen.width / 15, Screen.height / 15),"登录" ))
            {
                
                if (nickName.Length > 0)
                {
                    Dictionary<string, string> data = new Dictionary<string, string>();
                    data["guid"]                    = guid.ToString();
                    data["nickName"]                = nickName;

                    socketIO.Emit(SocketIOProtocol.ProtocolLogin, new JSONObject(data));
                }
            }  

           return;
        }

        GUI.Label(new Rect(0, 0, Screen.width, Screen.height - 200), chatContent);

        chatMessage = GUI.TextField(new Rect(0, Screen.height - 200, Screen.width - 200, 200), chatMessage);
        if (GUI.Button(new Rect(Screen.width - 200, Screen.height - 200, 200, 200), "Send"))
        {
            Dictionary<string, string> data = new Dictionary<string, string>();
            data["chatMessage"] = chatMessage;
            socketIO.Emit(SocketIOProtocol.ProtocolChat, new JSONObject(data));

            chatMessage = string.Empty;
        }
    }




    void OnAddEvemt()
    {
        socketIO.On("authenticated", (data)=> {
            // use the socket as usual
            Debug.Log("use the socket as usual");
            Debug.Log("authenticated, 验证成功" + data.data);
        });
        socketIO.On("unauthorized", (data) => {
            // use the socket as usual
            Debug.Log("unauthorized 验证失败,"+data.data);
        });

        socketIO.On(SocketIOProtocol.ProtocolLogin, (date) =>
        {
            JsonData jsonData = JsonMapper.ToObject(date.data.ToString());
            string message = string.Format("{0} : {1}", jsonData["nickName"], jsonData["chatMessage"]);
            chatContent += message + "\r\n";
            login = true;
        });

        socketIO.On(SocketIOProtocol.ProtocolChat, (date) =>
        {
            JsonData jsonData = JsonMapper.ToObject(date.data.ToString());
            string message = string.Format("{0} : {1}", jsonData["nickName"], jsonData["chatMessage"]);
            chatContent += message + "\r\n";
        });

        socketIO.On(SocketIOProtocol.ProtocolInfo, (date) =>
        {
           Debug.Log(date.data);
        });
    }
    void OnRemoveEvent()
    {
        socketIO.Off(SocketIOProtocol.ProtocolLogin);
        socketIO.Off(SocketIOProtocol.ProtocolChat);
        socketIO.Off(SocketIOProtocol.ProtocolInfo);
    }


 
}

Dome 下载地址:https://download.csdn.net/download/nicepainkiller/10502356


到这里。 Socket.IO for Unity3D 已经告一段落了。

等有时间 可以做下 Node.JS For Nginx 的分布式。以及 RPG 小游戏

猜你喜欢

转载自blog.csdn.net/nicepainkiller/article/details/80805472