这个是 Unity3D 和 Socket.IO 通信成功的截图。关于服务器端 我们已经昨天讲过了。今天主要讲一下客户端。并且 用 unity制作一个 聊天软件。 测试了 PC Android 都是OK的
我们先看下 客户端的 Socket 的事件顺序
Socket.IO内置了一些默认事件,我们在设计事件的时候应该避开默认的事件名称,并灵活运用这些默认事件。
服务器端事件:
io.sockets.on('connection', function(socket) {}):socket连接成功之后触发,用于初始化
socket.on('message', function(message, callback) {}):客户端通过socket.send来传送消息时触发此事件,message为传输的消息,callback是收到消息后要执行的回调
socket.on('anything', function(data) {}):收到任何事件时触发
socket.on('disconnect', function() {}):socket失去连接时触发(包括关闭浏览器,主动断开,掉线等任何断开连接的情况)
客户端事件:
connect:连接成功
connecting:正在连接
disconnect:断开连接
connect_failed:连接失败
error:错误发生,并且无法被其他事件类型所处理
message:同服务器端message事件
anything:同服务器端anything事件
reconnect_failed:重连失败
reconnect:成功重连
reconnecting:正在重连
在这里要提下客户端socket发起连接时的顺序。当第一次连接时,事件触发顺序为:connecting->connect;当失去连接时,事件触发顺序为:disconnect->reconnecting(可能进行多次)->connecting->reconnect->connect。
客户端我们用到一个插件:https://www.assetstore.unity3d.com/cn/#!/content/21721
这个插件虽然时间有点久了,但是还是挺好用的
unity3D新建一个场景 写个脚本 SocketController,随便挂在那里都行。 客户端就这个一个脚本
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();
}
else
{
socketIO = go.GetComponent();
if (socketIO == null)
{
socketIO = go.AddComponent();
}
}
socketIO.url = "ws://192.168.0.170:4567/socket.io/?EIO=3&transport=websocket";//本机测试地址 需要改成你配置的服务器
socketIO.Connect();
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 data = new Dictionary();
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 data = new Dictionary();
data["chatMessage"] = chatMessage;
socketIO.Emit(SocketIOProtocol.ProtocolChat, new JSONObject(data));
chatMessage = string.Empty;
}
}
void OnAddEvemt()
{
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);
}
}
服务器端的脚本
/*!
* 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'],
});
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;
}; ;
然后就好了
工程下载地址 https://download.csdn.net/download/nicepainkiller/10498219
你就可以玩了。
下一步 我准备加上 authorization 验证的环节避免恶意访问