文章目录
前言
这次了解的是项目通讯组件,大概过了一遍各个通讯组件的作用以及怎么互相通信调用的
提示:以下是本篇文章正文内容,下面案例可供参考
一、通讯组件
从上至下是
网络客户端&服务端监听
:一个在客户端发送信息,一个在服务器监听信息响应信息
封包处理器
:处理封包和协议的转换,网络上接收的数据序列化为Protro协议所接受的数据,也可反序列化把Protro协议的数据转为网络通信的数据格式
消息分发器&消息分配处理器
:服务端接收到客户端的信息 分发到服务器的各个通信模块,为了速度使用了多线程处理和分发器一起工作。
分发器只管分发不管给谁,分配器就是用来做一对一分配,维护哪个消息交给哪个模块处理
二、客户端 NetClient脚本
要想客户端与服务端通信,第一件事情就是要链接到服务端
客户端只提供发链接消息的功能
1.Connect 连接方法
int time 为重连时间,服务于断线重连
if(this.connecting) 判断有没有链接,如果有就结束
this.DoConnect() 开始链接
2.DoConnect 开始链接
使用try cath //防止链接中出错,抓取错误
new Soket 设置Soket //网络链接采用的是TCP协议
this.clientSocket.Blocking = true //设置阻塞的状态 客户端链接服务器时我们希望链接是阻塞的,因此我们能实时等待到链接的成果
this.clientSocket.BeginConnect() //链接 得到一个Result(请求)
result.AsyncWaitHandle.WailtOne() //这里使用了异步的方式,异步的时候并不会等待,因此我们需要使用AsyncWaitHandle来使它等待,WaitOne 会等待我们异步的事件,直到它完成才继续往下执行,反之如果不阻塞,将会直接往下执行,但会违背我们阻塞的初衷
---
catch(SocketException ex) //捕获 链接被拒绝或者链接异常这些属于网络专有的错误
catch(Exception e) //捕获常规异常
if(this.clientSocket.Connected) //前面执行完后,这里再会判断一次,继续判断本次的链接是否成功
this.clientSocket.Blocking=false; //链接成功之后就把阻塞清除,也为了后面玩起来和服务器进行通讯的时候是畅通无阻的
this.connecting = false //链接已完成,标记为false,表示现已不在链接,链接过程已完成
3.链接完成后发送信息 SendMessage()
NetMessage
协议自动生成的类
if(!this.Conected) 判断是否链接状态
this.Connect(); 没有就再链接一次
sendQueue.Equeue(message) 发送队列,为了不影响玩家操作(例如不小心在一帧发了一百个消息,但因为队列,不会在一瞬间发出)
4.Update()执行结束->客户端链接流程结束
if(this.KeepConnect()) 保证断线重连,判断状态
if(this.ProcessRecv()) 先接收(什么处理都不做),每一帧先看没有请求数据,有就收到之心执行链接
if(this.Connected) 收到后判断有没有异常(有没有和服务器连着)
this.ProcessSend(); 发送消息
this.ProcessMessage(); 处理消息。
消息分发器,直接分发信息
这里能直接分发的原因,是接收信息的时候,对数据进行了处理(ret=this.clientSocket.Poll(0,SelectMode.SelectRead))
;
int n = clientSocket.Receive
(把数据写入到缓存区)
this.packageHandle.ReceiveDate()
调用服务器的封包处理器接收数据的方法
总结
大概的了解了客户端的链接流程,底层没有过度的深入,目前只知道这些代码有什么用就行。