翻译了 利用 WCF duplex Service 【推送】数据到Siliverlight客户端 的双向通讯例子 收益菲浅, 终于通讯真正做起来了, 刚做好的聊天程序, 后面再补充笔记, 把一些关键问题解决调, 在优化一下.
访问地址: http://www.shareach.com:81/chat
代码下载:http://www.cnblogs.com/yinpengxiang/archive/2009/03/30/1424724.html
以前js版本的: http://www.shareach.com/chat.aspx对应
看了一周的WCF终于有点成果了. 服务端参考了MSDN的这个文章, 客户端参考了MSDN这个文章
看大家登录后测试情况, 这个 双向通讯还是不稳定, 经常有js错误出现,但是不影响正常使用
后续计划:
- 做公聊的聊天室,现在只有私聊的
- 完成登录状态即时更新, 现在人家走了一年也不知道
- 把前面测试的上传功能结合进来
- 想做一个相册
这么多功能先想想,不知道要到猴年马月搞定
遇到的问题/原因和解决办法吧
1.PollingDuplexHttpBinding.ReceiveTimeout 对应的超时问题 和 这个问题发现后的代码修改方式
这个问题用作IM通讯项目里可能会碰到, 这个属性是针对监听超时, MSDN上描述是”Gets or sets the interval of time that a connection can remain inactive, during which no application messages are received, before it is dropped.” 我开始一度以为,这个是针对整个通道的, 所以一直没有搞明白消息收发仍在正常继续,但又会有超时报错, 经过几天的反复验证,终于发现问题原因和症结了. 我出的错误信息如下:CompleteReceive:Receive on local address http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous?id=ce16853b-f9cb-47e8-b812-3ea66bda0c45 timed out after 00:01:30. The time allotted to this operation may have been a portion of a longer timeout.这是一个普通的超时错误, 这个错误不是针对通道的, 而是对每个异步监听的错误, 我把我错误原因描述一下, 但是没有想好解决方法.
这个错误是我启动了很多异步监听(不是一个), 我是抄MSDN上的例子. 每次发送消息后我都会调用LoopRecive等消息,然后消息接受完了以后我还调用LoopRecive等消息. 有很多这个监听轮询, 导致超时的. MSDN上的例子的void CompleteOpenChannel(IAsyncResult result)调用了ReceiveLoop(channel); void CompleteReceive(IAsyncResult result)里面有调用了 ReceiveLoop(channel); 他这个是同步方式在循环发送信息,所以不会出超时异常,我把 SendMessage做了一个消息缓冲池, 每次有消息我就批量的发出去了 而且都调用ReceiveLoop,导致很多监听等待. 主要是例子里面所有的通讯都是顺序的, 但是真实使用的时候不可能这样完全顺序的. 有可能几个消息同时到达客户端, 为了保证消息正常到达,我又有回复机制,这就导致又有RecieveLoop循环,呵呵恶性循环. 还没想到好办法,只是把他try catch调了.
其实我觉得这是一个好处,反正都是异步监听,异步发送,不会影响到通道, 所以我把代码做了修改, 把消息池都去掉了, 呵呵, 看下面:
MSDN相关代码
我
改了一下流程和发送方式, 去掉了前面加的消息发送池, 既然超时只是针对每次监听回调, 那么我可以怎么发消息都没事了, 也就是连接完成后,我把Channel提出来了, 把发送功能(SendMessage)单独的抛出来了, 以后就一直用它好了,除非通道异常了, 至于通道异常不是这个主题了上面的代码中,我可以任意的地方调用SendMessage, 这样就封装成了一个只有几个口的通讯类了, 其它都用了异常属性方法回调, 比较懒, 都是同步调用的,没有用异步方式. 那么那个异常就让他异常去吧, 反正不影响我通讯. 除非后面有好的解决方法.
还有一个就是那个SendMessageState类, 为了在异步发送完成后, 如果出错,知道原始消息是什么了, 但是有个问题就是站着内存, 不过消息不大,呵呵.
2. 异步调用,其它线程访问UI
前面好多地方为了使Silverlight不出错, 都加了Try Catch了, 也没处理(习惯不好,为了快速验证学过的东西), 而且很多回调都是同步的, 在界面上都没有看到错误在哪, 经常出了莫名奇妙的问题, 后来发现很多是因为通道接收到的消息都是uiThread.Post()方法出来的,导致了这个冲突, 后来做了那个调试日志才发现的. 置于怎么访问更新和处理UI看Silverlight中 非UI线程更新UI 的几种方法, 这和WinForm有点类似.
3.全屏模式下键盘无效了
这个问题比较恶心, 我感觉应该是个开关, 微软解释是什么操作安全问题, 全屏不让随便碰屏幕什么的. 如果是开关多好, 开始全屏感觉慢爽的. 发现全屏不能输入, 就不爽了.
4.IE 8
Ie 8 从Beta 开始我就安装了一次,为了那个Dev tool(和firebug类似), 发现不好用, RC的时候又是装了卸了, 正式版还是一样, SL在上面好多问题(是一个在聊天室告诉我的), 包括cnblog版面都是不正常, 又卸了. 这个问题应该不是这个里面的问题, 罗列一下吧.
5.客户端退出让Service即时知道
退出或者异常退出,还没找到办法及时让Service监测到,只有等待session过期才能检测到, 只能把session值设置小一点. 不知道有没有其它办法, 让Service快速知道客户端断了.
总的感觉, WCF 非常强大, Silverlight结合WCF做RIA应用觉得比Flash强, 那个SmartFoxServer好难用啊, 而且那个代码太难受.
上次看了CodePlex上的一个开源代码, 上传大文件的, 我上传了7G还没死, 后来不敢继续了, 我把他改了一下上传照片, 网址是 http://www.shareach.com:81/upload, 客户端就处理图片,很爽.
后面还要继续研究WCF其它的东西. good good study, day day up.