C#模拟服务器,Unity模拟客户端
效果图:
思路:客户端连接服务器发送上线消息,服务器记录所有user,然后广播给已经在线的玩家,同时发送所有玩家的名字给上线的用户,实现同步好友列表,这里用的是PopList制作的用户列表,更新显示上线消息的,这用的是TextList(NGUI制作的UI),在客户端异步发送环节,并没有在messagecenter中写派发发送消息的方法,因为懒呗,只写了一个派发收到消息的函数,通过收到消息中的协议的协议号处理消息,这里我用的协议是协议号(ushort)+消息的长度(ushort)+消息的内容(byte[]),也就是MessagePackage的一个实例,发送的时候把三个字段转成byte数组进行拼接发送,在MyTools工具类定义的就是操作数据的方法,那么服务器的流程也是和客户端一样的结构,不一样的就是具体的消息操作类逻辑
主要类:
客户端:
UITalkController:这个是挂在类,用来显示消息,和交互服务器连接
Client:封装套接字客户端Socket,用来与服务器通讯,包含,连接,断开,发送,接受等方法
IMessage:消息处理类的接口
MessageCenter:消息中心
OnLineState:上线信息的具体操作类
TalkState:聊天消息的具体操作类
TalkMessage:消息的包(protobuf工具生成,此类主要是承载通讯的消息,通过protobuf进行序列化与反序列化)
MessagePackage:发送和接受的包
MyTools:工具类,主要方法,封包,分包,序列化,反序列化
服务器:
Program:主函数,用于开启服务器
Server:封装服务器套接字,用于通讯
MyTools:工具类,主要方法,封包,分包,序列化,反序列化
IMessage:消息处理类的接口
MessageCenter:消息中心
OnLineState:上线信息的具体操作类
TalkState:聊天消息的具体操作类
TalkMessage:消息的包(protobuf工具生成,此类主要是承载通讯的消息,通过protobuf进行序列化与反序列化)
在编写的过程发现IMessage,MessageCenter,MyTools,TalkMessage,MessagePackage是通用的,原理基本都是一样的,下面贴出代码:
客户端:
挂载类:
using System.Collections.Generic;
using UnityEngine;
using day1_7MessageData;
using System.Text;
using Day1_7EVEServer;
public class UITalkController : MonoBehaviour {
//用户列表
public UIPopupList userPopList;
//消息输入框
public UIInput ipInput;
public UIInput portInput;
public UIInput messageInput;
public UIInput nickNameInput;
//消息显示文本
public UITextList textList;
public UIButton sendBtn;
public UIButton clearBtn;
public UIButton connectBtn;
public UIButton disConnectBtn;
public UIButton reConnectBtn;
// Use this for initialization
void Start () {
userPopList.AddItem("所有人");
//按钮注册事件,两种方式
sendBtn.onClick.Add(new EventDelegate(SendBtnHandler));
clearBtn.onClick.Add(new EventDelegate(ClearBtnHandler));
connectBtn.onClick.Add(new EventDelegate(ConnectBtnHandler));
UIEventListener.Get(disConnectBtn.gameObject).onClick += DisConnectBtnHandler;
UIEventListener.Get(reConnectBtn.gameObject).onClick += ReConnectBtnHandler;
}
/// <summary>
/// 上线用户添加方法
/// </summary>
private void UserFun()
{
List<string> list = userPopList.items;
for (int i = 0; i < MessageCenter.Instance.userList.Count; i++)
{
if (!list.Contains(MessageCenter.Instance.userList[i]))
{
userPopList.AddItem(MessageCenter.Instance.userList[i]);
}
}
}
/// 重新连接服务器
private void ReConnectBtnHandler(GameObject go)
{
Client.Instance.ReConnectToServer(ipInput.value,int.Parse(portInput.value));
}
/// <summary>
/// 断开连接
/// </summary>
/// <param name="go"></param>
private void DisConnectBtnHandler(GameObject go)
{
Client.Instance.DisConnectToServer();
}
/// <summary>
/// 连接服务器按钮
/// </summary>
private void ConnectBtnHandler()
{
Client.Instance.StartClient();
bool isOnline=Client.Instance.ConnectToServer(ipInput.value, int.Parse(portInput.value));
if (isOnline) {
SendOnlineMessage();
}
}
/// <summary>
/// 清屏按钮 <
using UnityEngine;
using day1_7MessageData;
using System.Text;
using Day1_7EVEServer;
public class UITalkController : MonoBehaviour {
//用户列表
public UIPopupList userPopList;
//消息输入框
public UIInput ipInput;
public UIInput portInput;
public UIInput messageInput;
public UIInput nickNameInput;
//消息显示文本
public UITextList textList;
public UIButton sendBtn;
public UIButton clearBtn;
public UIButton connectBtn;
public UIButton disConnectBtn;
public UIButton reConnectBtn;
// Use this for initialization
void Start () {
userPopList.AddItem("所有人");
//按钮注册事件,两种方式
sendBtn.onClick.Add(new EventDelegate(SendBtnHandler));
clearBtn.onClick.Add(new EventDelegate(ClearBtnHandler));
connectBtn.onClick.Add(new EventDelegate(ConnectBtnHandler));
UIEventListener.Get(disConnectBtn.gameObject).onClick += DisConnectBtnHandler;
UIEventListener.Get(reConnectBtn.gameObject).onClick += ReConnectBtnHandler;
}
/// <summary>
/// 上线用户添加方法
/// </summary>
private void UserFun()
{
List<string> list = userPopList.items;
for (int i = 0; i < MessageCenter.Instance.userList.Count; i++)
{
if (!list.Contains(MessageCenter.Instance.userList[i]))
{
userPopList.AddItem(MessageCenter.Instance.userList[i]);
}
}
}
/// 重新连接服务器
private void ReConnectBtnHandler(GameObject go)
{
Client.Instance.ReConnectToServer(ipInput.value,int.Parse(portInput.value));
}
/// <summary>
/// 断开连接
/// </summary>
/// <param name="go"></param>
private void DisConnectBtnHandler(GameObject go)
{
Client.Instance.DisConnectToServer();
}
/// <summary>
/// 连接服务器按钮
/// </summary>
private void ConnectBtnHandler()
{
Client.Instance.StartClient();
bool isOnline=Client.Instance.ConnectToServer(ipInput.value, int.Parse(portInput.value));
if (isOnline) {
SendOnlineMessage();
}
}
/// <summary>
/// 清屏按钮 <