Beispiel #1
0
        static void HandleNativeNetworkIoEvent(int kind, int status, int channel, IntPtr sid, IntPtr opaque)
        {
            var nsm = NetworkServiceManager.Instance;

            Debug.LogFormat("The channel connect_id={0}, bytes_transferred={1}", YASIO_NI.yasio_connect_id(nsm._service, channel),
                            YASIO_NI.yasio_bytes_transferred(nsm._service, channel));
            switch ((YASIO_NI.YEnums)kind)
            {
            case YASIO_NI.YEnums.YEK_PACKET:
                (int cmd, NativeDataView ud, Stream hold) = nsm._packeter.DecodePDU(YASIO_NI.yasio_unwrap_ptr(opaque, 0), YASIO_NI.yasio_unwrap_len(opaque, 0));
                nsm._packeter.HandleEvent(NetworkEvent.PACKET, cmd, ud, channel);
                hold?.Dispose();
                break;

            case YASIO_NI.YEnums.YEK_CONNECT_RESPONSE:
                if (status == 0)
                {
                    nsm.UpdateSession(channel, sid);
                    nsm.BroadcastEventToListeners(NetworkEventType.CONNECT_SUCCESS, 0, channel);
                    nsm._packeter.HandleEvent(NetworkEvent.CONNECT_SUCCESS, -1, NativeDataView.NullValue, channel);
                }
                else
                {
                    nsm.BroadcastEventToListeners(NetworkEventType.CONNECT_FAILED, status, channel);
                    nsm._packeter.HandleEvent(NetworkEvent.CONNECT_FAILED, -1, NativeDataView.NullValue, channel);
                }
                break;

            case YASIO_NI.YEnums.YEK_CONNECTION_LOST:
                nsm.BroadcastEventToListeners(NetworkEventType.CONNECTION_LOST, status, channel);
                nsm._packeter.HandleEvent(NetworkEvent.CONNECTION_LOST, -1, NativeDataView.NullValue, channel);
                break;
            }
        }
Beispiel #2
0
 unsafe public void EncodePDU(int cmd, NativeDataView ud, IntPtr ob)
 {
     YASIO_NI.yasio_ob_write_short(ob, (short)cmd);
     YASIO_NI.yasio_ob_write_int(ob, ud.len);             // packet size
     YASIO_NI.yasio_ob_write_int(ob, VERIFIED_MAGIC_NUM); // magic number
     YASIO_NI.yasio_ob_write_bytes(ob, ud.ptr, ud.len);   // ud
 }
Beispiel #3
0
        unsafe public void SendSerializedMsg(int cmd, NativeDataView ud, int channel = 0)
        {
            // The whole packet is sizeof(body) + sizeof(header), so no memory realloc
            IntPtr pdu = YASIO_NI.yasio_ob_new(ud.len + _packeter.GetHeaderSize());

            _packeter.EncodePDU(cmd, ud, pdu);
            if (channel < _sessions.Length)
            {
                IntPtr sid = _sessions[channel];
                if (sid != IntPtr.Zero)
                {
                    YASIO_NI.yasio_write_ob(_service, sid, pdu);
                }
                else
                {
                    Debug.LogFormat("Can't send message to the channel: {0}, the session not ok!", channel);
                }
            }
            else
            {
                Debug.LogFormat("Can't send message to the channel: {0}, the index is overflow, max allow value is:{1}", channel,
                                _sessions.Length);
            }

            YASIO_NI.yasio_ob_release(pdu);
        }
Beispiel #4
0
 /// <summary>
 ///
 /// </summary>
 public void Stop()
 {
     if (isRunning())
     {
         YASIO_NI.yasio_destroy_service(_service);
         _service = IntPtr.Zero;
     }
 }
Beispiel #5
0
 /// <summary>
 /// 获取链接状态的tcp.rtt, 如果未连接,则返回0
 /// </summary>
 /// <param name="channel"></param>
 /// <returns></returns>
 uint GetRTT(int channel = 0)
 {
     if (channel < _sessions.Length)
     {
         return(YASIO_NI.yasio_tcp_rtt(_sessions[channel]));
     }
     return(0);
 }
Beispiel #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="address"></param>
        /// <param name="port"></param>
        /// <param name="channel"></param>
        public void ListenAt(string address, ushort port, int channel)
        {
            string strParam = string.Format("{0};{1};{2}", channel, address, port);

            YASIO_NI.yasio_set_option(_service, (int)YASIO_NI.YEnums.YOPT_C_REMOTE_ENDPOINT, strParam);

            var reuseaddr = (int)YASIO_NI.YEnums.YCF_REUSEADDR;

            YASIO_NI.yasio_set_option(_service, (int)YASIO_NI.YEnums.YOPT_C_MOD_FLAGS, $"{channel};{reuseaddr};0");
            ListenAt(channel);
        }
Beispiel #7
0
        unsafe public (int, NativeDataView, Stream) DecodePDU(IntPtr bytes, int len)
        {
            Stream dataStream = new UnmanagedMemoryStream((byte *)bytes, len);

            try
            {
                using (var reader = new BinaryReader(dataStream, Encoding.ASCII, true))
                {
                    // 读取包头信息,magic number检验(这里也可以用hash摘要算法,计算消息体数据摘要)
                    int cmd      = IPAddress.NetworkToHostOrder(reader.ReadInt16());
                    int udLen    = IPAddress.NetworkToHostOrder(reader.ReadInt32());
                    int magicNum = IPAddress.NetworkToHostOrder(reader.ReadInt32());
                    reader.Dispose();

                    if (magicNum == VERIFIED_MAGIC_NUM)
                    {
                        // magic number校验正确
#if UNITY_EDITOR
                        if (DUMP_RECV_HEX)
                        {
                            int    bodyLen   = len - PROTO_HEADER_SIZE; // the udLen===bodyLen
                            string wholeHexs = YASIO_NI.DumpHex(bytes, len);
                            UnityEngine.Debug.LogFormat("cmd={0}, udLen/bodyLen={1}/{2}, wholeHexs: {3}\n", cmd, udLen, bodyLen, wholeHexs);
                            string bodyHexs = YASIO_NI.DumpHex(bytes + PROTO_HEADER_SIZE, bodyLen);
                            UnityEngine.Debug.LogFormat("cmd={0}, bodyHexs: {1}\n", cmd, bodyHexs);
                        }
#endif
                        NativeDataView ud = new NativeDataView {
                            ptr = bytes + PROTO_HEADER_SIZE, len = len - PROTO_HEADER_SIZE
                        };

                        return(cmd, ud, dataStream);
                    }
                    else
                    {
                        UnityEngine.Debug.LogErrorFormat("SampleNetworkPacketHandler.DecodePDU: check magic number failed, magicNum={0}, VERIFIED_MAGIC_NUM={1}", magicNum, VERIFIED_MAGIC_NUM);
                    }
                }
            }
            finally
            {
                dataStream?.Dispose();
            }

            return(-1, NativeDataView.NullValue, null);
        }
Beispiel #8
0
 /// <summary>
 /// 向远端发送数据
 /// </summary>
 /// <param name="bytes"></param>
 public void SendRaw(NativeDataView data, int channel)
 {
     if (channel < _sessions.Length)
     {
         IntPtr sid = _sessions[channel];
         if (sid != IntPtr.Zero)
         {
             YASIO_NI.yasio_write(_service, sid, data.ptr, data.len);
         }
         else
         {
             Debug.LogFormat("Can't send message to the channel: {0}, the session not ok!", channel);
         }
     }
     else
     {
         Debug.LogFormat("Can't send message to the channel: {0}, the index is overflow, max allow value is:{1}", channel,
                         _sessions.Length);
     }
 }
Beispiel #9
0
        /// <param name="maxChannels">支持并发连接数</param>
        /// <param name="packeter">数据包处理器</param>
        public void Start(int maxChannels, INetworkPacketHandler packeter)
        {
            if (isRunning())
            {
                return;
            }

            _packeter = packeter;

            _maxChannels = Math.Max(maxChannels, 1);

            _sessions = new IntPtr[_maxChannels];

            YASIO_NI.yasio_init_globals(HandleNativeConsolePrint);

            _service = YASIO_NI.yasio_create_service(_maxChannels, HandleNativeNetworkIoEvent);

            YASIO_NI.yasio_set_print_fn(_service, HandleNativeConsolePrint);

            for (int i = 0; i < _maxChannels; ++i)
            {
                SetOption(YASIO_NI.YEnums.YOPT_C_LFBFD_PARAMS, _packeter.GetOptions(i));
            }
        }
Beispiel #10
0
 /// <summary>
 /// 分派底层网络事件, tick调用
 /// </summary>
 public void OnUpdate()
 {
     YASIO_NI.yasio_dispatch(_service, 128);
 }
Beispiel #11
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="channel"></param>
 public void ListenAt(int channel)
 {
     YASIO_NI.yasio_open(_service, channel, (int)YASIO_NI.YEnums.YCK_TCP_SERVER);
 }
Beispiel #12
0
 /// <summary>
 /// 建立连接
 /// </summary>
 /// <param name="channel">连接信道</param>
 public void Connect(int channel = 0)
 {
     YASIO_NI.yasio_open(_service, channel, (int)YASIO_NI.YEnums.YCK_TCP_CLIENT);
 }
Beispiel #13
0
 public void Disconnect(int channel = 0)
 {
     YASIO_NI.yasio_close(_service, channel);
 }
Beispiel #14
0
        /// <summary>
        /// 设置网络选项
        /// </summary>
        /// <param name="opt">
        ///
        /// </param>
        /// <param name="strParam">use ';' to split parameters, such as "0;ip138.com;80</param>

        public void SetOption(YASIO_NI.YEnums opt, string strParam)
        {
            YASIO_NI.yasio_set_option(_service, (int)opt, strParam);
        }