包包版网络游戏大厅+桥牌系统 4.终于可以聊天了
2008-07-31 17:51
309 查看
返回目录
有了上一章所搭建的网络通信框架,我们就可以自由发挥了。只要把握好HandShake的顺序,就可以了。比如说我下面要介绍的大厅里的聊天机制,就是通过实现了503和504协议的“有问必答”原理。
重构后的版本,代码在这里下载:PlayCard 2.2
聊天室的截图如下,以下是一个Server端和两个Client端(注意到,kitty是最后登录的,所以看不到先前的聊天信息):
Code
public class MessageEventArgs : EventArgs
{
private string msg;
public string Message
{
get
{
return msg;
}
set
{
msg = value;
}
}
}
Client类
添加MessageReceived事件
public event EventHandler<MessageEventArgs> MessageReceived;
在BuildText方法中添加对503协议的处理
case "503":
if (MessageReceived != null)
{
ChatMessage meg = (ChatMessage)obj;
MessageEventArgs e = new MessageEventArgs();
e.Message = meg.Message;
MessageReceived(this, e);
}
break;
MainThread类
将OnMessageReceived方法附属到新添加的事件MessageReceived上:
newClient.MessageReceived += OnMessageReceived;
而添加OnMessageReceived方法如下,从而把这条聊天信息转发给所有在线用户:
public void OnMessageReceived(object sender, MessageEventArgs e)
{
//Message sender client
Client temp = (Client)sender;
AddLog(temp.UserName + " :" + e.Message);
ChatMessage chat = new ChatMessage();
chat.Protocol = "504";
chat.UserName = temp.UserName;
chat.Message = e.Message;
byte[] message = SerializationFormatter.GetSerializationBytes(chat);
Client tempClient;
DataTable dt = ClientList.Instance().GetUserList();
foreach (DataRow row in dt.Rows)
{
string uid = (string)row["UserID"];
tempClient = (Client)clientTable[uid];
tempClient.Send(message);
}
}
以上是Client端和Server端的修改,归结出“程咬金三板斧”,以后每次添加新协议都如法炮制:
1.携带新信息的协议,就在CommonClassLibrary类库添加相应的实体类,派生于CommonProtocol基类。
2.永远是Client端先发Request请求,也就是一个单数协议,如501(登录)、503(发聊天消息),以后还会有很多。这是一个主动的动作,来自UI的的操作,注意,这里只发送消息就可以,而不要等待结果——所谓异步编程的思路。让我们再来看一下点击发送按钮的方法:
if (txtMessage.Text.Trim() != "")
{
ChatMessage u = new ChatMessage();
u.Protocol = "503";
u.Message = txtMessage.Text.Trim();
SendText(SerializationFormatter.GetSerializationBytes(u));
txtMessage.Text = "";
}
3.Server端永远是被动的接收来自Client的Request请求——一个单数协议,在BuildText方法中对其进行解析后,触发主线程的相应事件,于是在相应的方法中,发送偶数协议,也就是Response。这里,可能是发给原先Request的Client端(如502协议登录验证结果),也可能是群发给其他Client端(如504协议转发聊天信息)
4.无论Server端还是Client端,都是在BuildText方法中对接收到的数据包进行反序列化,然后根据协议的不同进行不同的处理。以后我们每次添加新协议,都要这里加上case分支语句,注意到Server端处理单数协议,Client处理偶数协议。
相应的,在这些处理模块中,要进行方法回调,从而操作主线程或UI。这里,Server端使用了事件机制;而Client端使用了委托回调机制。
补充:小赵指出我使用了HashTable这个老古董存储client对象不是很好,于是我将其改造为Dictionary<KValue, TValue>范型:
private Dictionary<string, Client> clientTable;
clientTable = new Dictionary<string, Client>();
也许有人会问,游戏大厅需要聊天么?是的,可以没有这个功能。我演示的目的是承上启下,介绍一下在我这个框架下如何轻松地开发新功能,制定一个套路,为下面的大厅通信打下基础。
此外,在Client端,目前还没有显示其他用户进入或离开的消息,以及显示用户列表的功能。
下一章,我要搭建游戏大厅,并对聊天功能进行改进。
有了上一章所搭建的网络通信框架,我们就可以自由发挥了。只要把握好HandShake的顺序,就可以了。比如说我下面要介绍的大厅里的聊天机制,就是通过实现了503和504协议的“有问必答”原理。
重构后的版本,代码在这里下载:PlayCard 2.2
聊天室的截图如下,以下是一个Server端和两个Client端(注意到,kitty是最后登录的,所以看不到先前的聊天信息):
Code
public class MessageEventArgs : EventArgs
{
private string msg;
public string Message
{
get
{
return msg;
}
set
{
msg = value;
}
}
}
Client类
添加MessageReceived事件
public event EventHandler<MessageEventArgs> MessageReceived;
在BuildText方法中添加对503协议的处理
case "503":
if (MessageReceived != null)
{
ChatMessage meg = (ChatMessage)obj;
MessageEventArgs e = new MessageEventArgs();
e.Message = meg.Message;
MessageReceived(this, e);
}
break;
MainThread类
将OnMessageReceived方法附属到新添加的事件MessageReceived上:
newClient.MessageReceived += OnMessageReceived;
而添加OnMessageReceived方法如下,从而把这条聊天信息转发给所有在线用户:
public void OnMessageReceived(object sender, MessageEventArgs e)
{
//Message sender client
Client temp = (Client)sender;
AddLog(temp.UserName + " :" + e.Message);
ChatMessage chat = new ChatMessage();
chat.Protocol = "504";
chat.UserName = temp.UserName;
chat.Message = e.Message;
byte[] message = SerializationFormatter.GetSerializationBytes(chat);
Client tempClient;
DataTable dt = ClientList.Instance().GetUserList();
foreach (DataRow row in dt.Rows)
{
string uid = (string)row["UserID"];
tempClient = (Client)clientTable[uid];
tempClient.Send(message);
}
}
以上是Client端和Server端的修改,归结出“程咬金三板斧”,以后每次添加新协议都如法炮制:
1.携带新信息的协议,就在CommonClassLibrary类库添加相应的实体类,派生于CommonProtocol基类。
2.永远是Client端先发Request请求,也就是一个单数协议,如501(登录)、503(发聊天消息),以后还会有很多。这是一个主动的动作,来自UI的的操作,注意,这里只发送消息就可以,而不要等待结果——所谓异步编程的思路。让我们再来看一下点击发送按钮的方法:
if (txtMessage.Text.Trim() != "")
{
ChatMessage u = new ChatMessage();
u.Protocol = "503";
u.Message = txtMessage.Text.Trim();
SendText(SerializationFormatter.GetSerializationBytes(u));
txtMessage.Text = "";
}
3.Server端永远是被动的接收来自Client的Request请求——一个单数协议,在BuildText方法中对其进行解析后,触发主线程的相应事件,于是在相应的方法中,发送偶数协议,也就是Response。这里,可能是发给原先Request的Client端(如502协议登录验证结果),也可能是群发给其他Client端(如504协议转发聊天信息)
4.无论Server端还是Client端,都是在BuildText方法中对接收到的数据包进行反序列化,然后根据协议的不同进行不同的处理。以后我们每次添加新协议,都要这里加上case分支语句,注意到Server端处理单数协议,Client处理偶数协议。
相应的,在这些处理模块中,要进行方法回调,从而操作主线程或UI。这里,Server端使用了事件机制;而Client端使用了委托回调机制。
补充:小赵指出我使用了HashTable这个老古董存储client对象不是很好,于是我将其改造为Dictionary<KValue, TValue>范型:
private Dictionary<string, Client> clientTable;
clientTable = new Dictionary<string, Client>();
也许有人会问,游戏大厅需要聊天么?是的,可以没有这个功能。我演示的目的是承上启下,介绍一下在我这个框架下如何轻松地开发新功能,制定一个套路,为下面的大厅通信打下基础。
此外,在Client端,目前还没有显示其他用户进入或离开的消息,以及显示用户列表的功能。
下一章,我要搭建游戏大厅,并对聊天功能进行改进。
相关文章推荐
- 包包版网络游戏大厅+桥牌系统 2.游戏大厅的基本架构
- 包包版网络游戏大厅+桥牌系统 附录1 通信协议
- 包包版网络游戏大厅+桥牌系统 1.发牌
- 包包版网络游戏大厅+桥牌系统 目录 更新到第4章
- 包包版网络游戏大厅+桥牌系统 序
- 包包版网络游戏大厅+桥牌系统 3.从登录说起
- 我做的通用象棋连线器,可以连接到游戏大厅
- 网络通信终于可以了
- FlexAir 开源版-多人视频聊天室,网络远程多人视频会议系统((Flex,Fms3联合开发))<视频聊天,会议开发实战>
- [TORQUE游戏引擎DTS文件技术总结]终于搞定太史慈的DTS,现在可以完全使用ORC的DSQ文件了
- 用Robot Framework+python来测试基于socket通讯的C/S系统(网络游戏)
- Java网络编程基础(四)---基于TCP的简单聊天系统
- 手机网络游戏系统架构图
- 忙碌了一整天,终于弄好了免费电脑版的KTV点歌系统,以后可以K歌了!
- 基于网络游戏资料数据的搜索系统的设计
- 江苏中理网络科技乾坤云部署系统可以实现
- Unity网络教程翻译(三)多人游戏大厅
- 多网卡网络提示IP冲突时要查看系统日志,可以查到具体冲突的IP
- XNA Game Studio是一套有着强大功能和简单界面的游戏制作平台,游戏开发商和游戏玩家都可以使用这套工具开发针对Windows XP以及Xbox360的游戏,XNA Game Studio分为两种版本,一种是面向初学者的EXPRESS版本,还有一种是面向专业用户的专业版。用户使用EXPRESS版本开发游戏完全免费,并且可以随意在PC上发行,不过用该工具开发的游戏若是在360上网络发行,就需要交纳99美元的年费。
- 呵呵呵呵。。。系统还原了,终于可以用IE登陆百度了