funny / snet

A long lasting connection protocol for mobile applications that supports reconnection and encryption.
Do What The F*ck You Want To Public License
177 stars 36 forks source link

[C#] 发送的消息应该保证顺序 #5

Open chentmin opened 7 years ago

chentmin commented 7 years ago

现在在C#端, 就算调用方是单线程在调用发送, 底下会把发送放到个线程池中, 短时间内发送多条消息时, 更容易发生消息的顺序改变的情况.

这样的话, 就要求使用snet的项目对C#发过来的消息的顺序不能有要求, 甚至可能在逻辑上会有问题, 比如客户端是先跳再放的技能, 服务器先收到了放技能的消息.


        public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            AsyncResult ar1 = new AsyncResult (callback, state);
            ThreadPool.QueueUserWorkItem ((object ar2) => {
                AsyncResult ar3 = (AsyncResult)ar2;
                try {
                    Write(buffer, offset, count);
                } catch(Exception ex) {
                    ar3.Error = ex;
                }
                ar3.IsCompleted = true;
                ((ManualResetEvent)ar3.AsyncWaitHandle).Set();
                if (ar3.Callback != null)
                    ar3.Callback(ar3);
            }, ar1);
            return ar1;
        }
chentmin commented 7 years ago

本来就要在写入的时候把要发送的字节数copy到rewriter以备之后重发, 不如就在写入的线程里, 只把要写的字节数刷到rewriter里, 然后通知负责flush的线程有数据要发送. flush线程负责从上次刷成功的index开始, 写入剩余未写入的部分. 这样子修改的好处是

需要额外处理发送得很慢的情况, 逻辑线程要写数据时, 未发送的数据数量超过了rewriter的大小. 可以考虑

patricksuo commented 6 years ago

@chentmin 请问你们有修复这个问题吗?

chentmin commented 6 years ago

木有, 偶c#不溜