最近在基于做个C/S即时聊天的东西,遇到觉得是两个比较棘手的问题:
先说服务端的查询的问题吧,由于服务端是根据socket识别客户端的,
而一个用户有几种属性,最基本就是用户名(唯一不变)和昵称(可修改)了。
一般来说服务端需要处理几种事件:
1,某用户登录,获取到用户名,昵称信息,还有对应的一个socket
2,某用户请求修改他的昵称或者其他信息
3,将消息发送给指定用户名的的用户(消息可能是管理员发送,也可能来自其他用户)
4,某用户下线了
5,也是最麻烦的。服务端中的列表控件根据管理员的拖动,需要重绘index从x到y的用户信息(譬如进度条在中间,而且这几个用户信息发生了变动,就需要重绘)。
为了能够尽快响应用户请求,我用了个哈希表将socket与用户名绑定了起来,酱紫的话可以迅速从socket
找到需要对应的用户,但是有个问题就麻烦了,当需要按照index(上线的先后顺序)查找用户时候,哈希表就力不从心了。这个不知道大家什么想法,可以分享下。
另一方面,客户端遇到的问题。客户端一个UI界面,一个维护网络连接的线程。网络连接作为单体对象存在。
在连接服务器的时候,我这边是酱紫:
do
{
try
{
//尝试连接
sharedConnection.ConnectToServer();
}
catch(...)
{
//发生了异常,模拟QQ的断线自动重连
cout << "连接发生了异常,2 分钟后重连"
Sleep(2*60*1000);
}
}while(this->m_shouldExit == false);//还不需要退出,继续尝试连接
酱紫的话,在用户退出或者客户端需要手动重连的时候会出现问题。
理想情况下,我不希望杀掉线程,希望它正常结束,酱紫能有效避免内存泄漏等问题。那么在退出客户端或者手动重连
的时候,我会sharedConnection.Disconnect()一次(m_shouldExit置true),
然后等待上一个连接的线程结束(WaitForSingleObject),以方便我重开线程。
但是,如果上个线程死在 Sleep(2*60*1000); 上面,那么我的WaitForSingleObject将不得不
等待2分钟。这个无论是对关闭客户端还是手动重连,都是客户无法接受的。
现在我的做法是在Sleep中加个for循环,每次Sleep(500),然后检查下m_shouldExit,决定是不是要退出
但是觉得做法太猥琐,不知道有没有更好的解决方案。
谢谢大家