赞
踩
注:发文章我不像某些大咖只发大概思路,每一步我的操作我都会写下来,如果实在看不懂就去下载我的案例哈,本文章只研究下如何互发文字通讯,web端互发图片的等我研究出来再发哈
Unity做聊天室,网上大多数都是通过socket做的,我之前也尝试了一下不难,但是最近的项目都是发布成webgl,我发现一个问题,那就是web端不支持socket,通过查找资料,我找到另一个通讯方式——websocket,先普及型websocket。
WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP请求完成。
1.原理:
WebSocket同HTTP一样也是应用层的协议,但是它是一种双向通信协议,是建立在TCP之上的。
2.连接过程 —— 握手过程
WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。
Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。
WebSocket则是一个典型的应用层协议。
Socket是传输控制层协议,WebSocket是应用层协议。
5.在Unity中,WebSocket比Socket更适用各个平台的开发
以下介绍下Unity发布Web,通讯功能如何做,以聊天室为案例
1.导入BestHttp插件
这个插件包含所有即使通讯方式的简单使用,下载地址为BestHttp通讯插件-C#文档类资源-CSDN下载
2.布置UI
这边我只做了两个简易界面,一个是登录界面,一个是聊天窗口界面,功能如图所示
3.构建服务端
使用VS新建项目C#控制台
通过包管理器,引用websocket和litjson相关组件
除了控制台自带的类Program,还需新建类MessageData,ClientController,各代码如下:
- using SuperSocket.SocketBase;
- using SuperWebSocket;
- using System;
- using System.Collections.Generic;
-
- class Program
- {
- public static List<ClientController> clientControllerList = new List<ClientController>();
- static void Main(string[] args)
- {
- // Console.WriteLine("Press any key to start the WebSocketServer!");
-
- //Console.ReadKey();
- // Console.WriteLine();
-
- var appServer = new WebSocketServer();
-
-
- //Setup the appServer
- if (!appServer.Setup(2012)) //Setup with listening port
- {
- Console.WriteLine("Failed to setup!");
- Console.ReadKey();
- return;
- }
-
- appServer.NewSessionConnected += delegate (WebSocketSession session)
- {
- // Console.WriteLine("新玩家加入: " + session.SessionID);
- // session.Send("新玩家加入: " + session.SessionID);
- };
-
- appServer.SessionClosed += delegate (WebSocketSession session, CloseReason value)
- {
-
- for (int i = 0; i < clientControllerList.Count; i++)
- {
- if (session.SessionID == clientControllerList[i].session.SessionID)
- {
- ClientController client = clientControllerList[i];
- client .SendMessageDataToAllClientWithOutSelf(client.nickName + "离开聊天室");
- Console.WriteLine(client.nickName+ "离开聊天室");
- clientControllerList.Remove(clientControllerList[i]);
- return ;
- }
- }
-
-
- };
- appServer.NewMessageReceived += delegate (WebSocketSession session, string value)
- {
- MessageData data = LitJson.JsonMapper.ToObject<MessageData>(value);
- ClientController clientController =GetClient(session);
-
- string msg = "";
- switch (data.msgType)
- {
-
- case MessageType.Login://如果是登陆消息
- clientController.nickName = data.nickname;
-
- // session.Send("玩家加入: " + data.name);
- clientControllerList.Add(clientController);
- msg = clientController.nickName + "加入聊天室";
- Console.WriteLine(clientController.nickName + "加入聊天室");
- break;
- case MessageType.Chat://如果是聊天消息
- Console.WriteLine(clientController.nickName + "说: " + data.msg);
- data.nickname = clientController.nickName;
- msg = LitJson.JsonMapper.ToJson(data);
- break;
- case MessageType.LogOut://客户端请求退出
-
- Console.WriteLine(clientController.nickName + "离开聊天室");
- clientControllerList.Remove(clientController);
- msg = clientController.nickName + "离开聊天室";
-
- break;
- }
- clientController.SendMessageDataToAllClientWithOutSelf(msg);
-
- };
- Console.WriteLine();
-
- //Try to start the appServer
- if (!appServer.Start())
- {
- Console.WriteLine("Failed to start!");
- Console.ReadKey();
- return;
- }
-
- Console.WriteLine("The server started successfully, press key 'q' to stop it!");
-
- while (Console.ReadKey().KeyChar != 'q')
- {
- Console.WriteLine();
- continue;
- }
-
- //Stop the appServer
- appServer.Stop();
-
- Console.WriteLine();
- Console.WriteLine("The server was stopped!");
- Console.ReadKey();
- }
-
- public static ClientController GetClient(WebSocketSession session)
- {
- for (int i = 0; i < clientControllerList.Count; i++)
- {
- if (session.SessionID == clientControllerList[i].session.SessionID)
- {
- return clientControllerList[i];
- }
- }
- return new ClientController(session);
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- using SuperWebSocket;
- using System;
-
- class ClientController
- {
- /// <summary>
- /// 用户链接的通道
- /// </summary>
- public WebSocketSession session;
- /// <summary>
- /// 昵称
- /// </summary>
- public string nickName;
- //接收的线程
-
- public ClientController(WebSocketSession socket)
- {
- session= socket;
-
- }
-
-
- /// <summary>
- /// 广播消息,排除掉自己
- /// </summary>
- /// <param name="data"></param>
- public void SendMessageDataToAllClientWithOutSelf(string data)
- {
- //5 i=3
- for (int i = 0; i < Program.clientControllerList.Count; i++)
- {
- if (Program.clientControllerList[i] != this)
- {
- Program.clientControllerList[i].SendToClient(data);
- }
-
-
- }
- }
-
-
- void SendToClient(string data)
- {
- session.Send(data);
- }
-
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- /// <summary>
- /// 简单的协议类型
- /// </summary>
- public enum MessageType
- {
- Chat = 0,//聊天
- Login = 1,//登陆
- LogOut = 2,//登出
- }
- /// <summary>
- /// 消息体
- /// </summary>
- public class MessageData
- {
- /// <summary>
- /// 消息类型
- /// </summary>
- public MessageType msgType;
- /// <summary>
- /// 消息内容
- /// </summary>
- public string msg;
- public string nickname;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
此时点击运行,即可运行服务端
4.客户端代码
新建类WebSocketTest,MessageData,ChatItem,代码如下:
- using LitJson;
- /// <summary>
- /// 简单的协议类型
- /// </summary>
- public enum MessageType
- {
- Chat = 0,//聊天
- Login = 1,//登陆
- LogOut = 2,//登出
- }
- /// <summary>
- /// 消息体
- /// </summary>
- public class MessageData
- {
- /// <summary>
- /// 消息类型
- /// </summary>
- public MessageType msgType;
- /// <summary>
- /// 消息内容
- /// </summary>
- public string msg;
- public string nickname;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- using System;
- using UnityEngine;
- using BestHTTP;
- using BestHTTP.WebSocket;
- using UnityEngine.UI;
- using BestHTTP.Examples.Helpers;
-
- namespace BestHTTP.Examples.Websockets
- {
- public class WebSocketTest : BestHTTP.Examples.Helpers.SampleBase
- {
- // [SerializeField]
- // [Tooltip("The WebSocket address to connect")]
- private string address = "ws://192.168.2.50:2012";
-
- [SerializeField]
- private InputField name_input;
- [SerializeField]
- private InputField content_input;
-
- [SerializeField]
- private ScrollRect _scrollRect;
-
- [SerializeField]
- private RectTransform _contentRoot;
-
- [SerializeField]
- private TextListItem _listItemPrefab;
-
- [SerializeField]
- private int _maxListItemEntries = 100;
-
-
-
-
- #pragma warning restore
-
- /// <summary>
- /// Saved WebSocket instance
- /// </summary>
- WebSocket.WebSocket webSocket;
- public GameObject loginGo;
- public GameObject chatGo;
-
- protected override void Start()
- {
- base.Start();
- }
- public void LoginIn()
- {
- if (name_input.text == "" || name_input.text == null)
- return;
- // Create the WebSocket instance
- this.webSocket = new WebSocket.WebSocket(new Uri(address));
-
- #if !UNITY_WEBGL
- this.webSocket.StartPingThread = true;
-
- #if !BESTHTTP_DISABLE_PROXY
- if (HTTPManager.Proxy != null)
- this.webSocket.InternalRequest.Proxy = new HTTPProxy(HTTPManager.Proxy.Address, HTTPManager.Proxy.Credentials, false);
- #endif
- #endif
-
- // Subscribe to the WS events
- this.webSocket.OnOpen += OnOpen;
- this.webSocket.OnMessage += OnMessageReceived;
- this.webSocket.OnClosed += OnClosed;
- this.webSocket.OnError += OnError;
-
- // Start connecting to the server
- this.webSocket.Open();
- // AddText("Connecting...");
-
- }
- public void Chat()
- {
- if (content_input.text == "" || content_input.text == null)
- return;
- MessageData data = new MessageData();
- data.msgType = MessageType.Chat;
- data.msg = content_input.text;
- string json = JsonUtility.ToJson(data);
- webSocket.Send(json);
- ChatItem chatItem = (ChatItem)AddText(string.Format(" <color=yellow>我:</color>\n{0}",data.msg));
- chatItem.AddLeftPadding(20);
- chatItem.SetTextAlignment(TextAnchor.MiddleRight);
-
- }
-
-
- public void LoginOut()
- {
- MessageData data = new MessageData();
- data.msgType = MessageType.LogOut;
- data.msg = "退出";
- string json = JsonUtility.ToJson(data);
- webSocket.Send(json);
- webSocket.Close(1000, "Bye!");
-
- webSocket.OnOpen -= OnOpen;
- webSocket.OnMessage -= OnMessageReceived;
- webSocket.OnClosed -= OnClosed;
- webSocket = null;
- AddText("Closing!");
- loginGo.SetActive(true);
- chatGo.SetActive(false);
-
- }
-
-
- #region WebSocket Event Handlers
-
- /// <summary>
- /// Called when the web socket is open, and we are ready to send and receive data
- /// </summary>
- void OnOpen(WebSocket.WebSocket ws)
- {
- AddText("WebSocket Open!");
- MessageData data = new MessageData();
- data.msgType = MessageType.Login;
- data.nickname = name_input.text;
- string json = JsonUtility.ToJson(data);
- webSocket.Send(json);
- loginGo.SetActive(false);
- chatGo.SetActive(true);
- }
-
-
-
- /// <summary>
- /// Called when we received a text message from the server
- /// </summary>
- void OnMessageReceived(WebSocket.WebSocket ws, string message)
- {
- try
- {
- MessageData data = JsonUtility.FromJson<MessageData>(message);
- AddText(string.Format(" <color=yellow>{0}:</color>\n{1}", data.nickname,data.msg))
- .AddLeftPadding(20);
- }
- catch (System.Exception ex)
- {
- AddText(string.Format(" <color=yellow>{0}</color>", message))
- .AddLeftPadding(20);
- }
-
- }
-
- /// <summary>
- /// Called when the web socket closed
- /// </summary>
- void OnClosed(WebSocket.WebSocket ws, UInt16 code, string message)
- {
- AddText(string.Format("WebSocket closed! Code: {0} Message: {1}", code, message));
-
- webSocket = null;
-
-
- }
-
- /// <summary>
- /// Called when an error occured on client side
- /// </summary>
- void OnError(WebSocket.WebSocket ws, string error)
- {
- AddText(string.Format("An error occured: <color=red>{0}</color>", error));
-
- webSocket = null;
-
-
- }
-
- #endregion
-
-
-
- private TextListItem AddText(string text)
- {
- return GUIHelper.AddText(this._listItemPrefab, this._contentRoot, text, this._maxListItemEntries, this._scrollRect);
- }
-
- void OnDestroy()
- {
- if (this.webSocket != null)
- {
- this.webSocket.Close();
- this.webSocket = null;
- }
- }
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- namespace BestHTTP.Examples.Helpers
- {
- public class ChatItem : TextListItem
- {
-
- public void SetTextAlignment(TextAnchor textAnchor){
- _text.alignment=textAnchor;
- }
- }
- }
5.UI绑定功能
先复制一个“TextListItem”预制件,插件BestHttp里面有,然后去除它本身的脚本,挂上ChatItem脚本,成为一个新的预制件,供后面使用。
挂载脚本并赋值
将登陆按钮绑定登陆方法,发送按钮绑定发送方法
最后我们复制两个聊天系统,运行查看结果
打包web同样适用
demo:unitywebsocket聊天室案例-Unity3D文档类资源-CSDN下载
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。