Unity【Multiplayer 多人在线】- Socket 通用服务端框架(六)、单点发送和广播数据
【摘要】
介绍
在阅读了罗培羽著作的Unity3D网络游戏实战一书后,博主综合自己的开发经验与考虑进行部分修改和调整,将通用的客户端网络模块和通用的服务端框架进行提取,形成专栏,介绍Socket网络编程,希望对其他人有所帮助。目录如下:
一、通用服...
介绍
在阅读了罗培羽著作的Unity3D网络游戏实战一书后,博主综合自己的开发经验与考虑进行部分修改和调整,将通用的客户端网络模块和通用的服务端框架进行提取,形成专栏,介绍Socket网络编程,希望对其他人有所帮助。目录如下:
一、通用服务端框架
(六)、单点发送和广播数据
二、通用客户端网络模块
本篇内容:
单点发送:
定义写入队列:
-
//写入队列
-
private readonly static Queue<ByteArray> writeQueue = new Queue<ByteArray>();
发送方法Send接受两个参数:第一个参数为客户端信息对象,代表要将协议发送给哪个客户端;第二个参数proto代表要发送的协议对象。发送之前先进行状态判断,确保客户端连接有效。代码如下:
-
/// <summary>
-
/// 向客户端发送协议(单点发送)
-
/// </summary>
-
/// <param name="client">客户端</param>
-
/// <param name="proto">协议</param>
-
public static void Send(Client client, IExtensible proto)
-
{
-
//状态判断
-
if (client == null || !client.socket.Connected) return;
-
//数据编码
-
byte[] nameBytes = ProtoUtility.EncodeName(proto);
-
byte[] bodyBytes = ProtoUtility.Encode(proto);
-
int length = nameBytes.Length + bodyBytes.Length;
-
byte[] sendBytes = new byte[2 + length];
-
//组装长度
-
sendBytes[0] = (byte)(length % 256);
-
sendBytes[1] = (byte)(length / 256);
-
//组装名字
-
Array.Copy(nameBytes, 0, sendBytes, 2, nameBytes.Length);
-
//组装消息体
-
Array.Copy(bodyBytes, 0, sendBytes, 2 + nameBytes.Length, bodyBytes.Length);
-
//写入队列
-
ByteArray byteArray = new ByteArray(sendBytes);
-
lock (writeQueue)
-
{
-
writeQueue.Enqueue(byteArray);
-
}
-
if (writeQueue.Count == 1)
-
{
-
//发送
-
client.socket.BeginSend(sendBytes, 0, sendBytes.Length, 0, SendCallback, client.socket);
-
}
-
}
Send回调:
-
//发送回调
-
private static void SendCallback(IAsyncResult ar)
-
{
-
Socket socket = ar.AsyncState as Socket;
-
//状态判断
-
if (socket == null || !socket.Connected) return;
-
//结束发送
-
int length = socket.EndSend(ar);
-
ByteArray? byteArray;
-
lock (writeQueue)
-
{
-
byteArray = writeQueue.First();
-
}
-
//完整发送
-
byteArray.readIdx += length;
-
if (byteArray.length == 0)
-
{
-
lock (writeQueue)
-
{
-
writeQueue.Dequeue();
-
byteArray = writeQueue.Count > 0 ? writeQueue.First() : null;
-
}
-
}
-
//继续发送
-
if (byteArray != null)
-
{
-
socket.BeginSend(byteArray.bytes, byteArray.readIdx, byteArray.remain, 0, SendCallback, socket);
-
}
-
}
广播数据:
向所有客户端发送数据:
-
/// <summary>
-
/// 向所有客户端发送协议(广播)
-
/// </summary>
-
/// <param name="proto">协议</param>
-
public static void Send(IExtensible proto)
-
{
-
foreach (Client client in clients.Values)
-
{
-
Send(client, proto);
-
}
-
}
参考资料:《Unity3D网络游戏实战》(第2版)罗培羽 著
文章来源: coderz.blog.csdn.net,作者:CoderZ1010,版权归原作者所有,如需转载,请联系作者。
原文链接:coderz.blog.csdn.net/article/details/124055482
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)