MyBitConverter <long> _NotifyIDConverter = new MyBitConverter <long>(); // converter dùng để convert byte thành long, số long nhận được chính là notificationID được yêu cầu bởi client
        #endregion

        public ClientCommunicator(Params.RawNotificationClientCommunicatorParams param)
        {
            _Param = param;
            server = new TCPServer.TCPServer(_Param.ListenPort);
            // đăng ký sự kiện nhận được một gói tin từ client
            server.OnPacketReceived += (s, e) =>
            {
                FromClientPacket packet = null;
                try
                {
                    packet = PacketConverter.BytesToObject(e.Data);
                }
                catch
                {
                    // Bên ngoài gửi gói tin không đúng định dạng, có thể do lỗi đường truyền cũng có thể do ý đồ phá hoại
                    e.RespondToClient(ResultConverter.ObjectToBytes(new FromServerPacket(ServerResult.DataCorrupt, null)));
                    e.CloseConnection();
                    return;
                }
                switch (packet.Type)
                {
                case FromClientPacketType.Register:
                {
                    RegisterPacketData data = packet.Data as RegisterPacketData;
                    e.RespondToClient(ResultConverter.ObjectToBytes(new FromServerPacket(Register(data), null)));
                    e.CloseConnection();
                }
                break;

                case FromClientPacketType.GetNotificationContent:
                {
                    GetNotificationContentPacketData data = packet.Data as GetNotificationContentPacketData;
                    ServerResult result;
                    // lấy ra content
                    byte[] content = NotificationContent(data.NotificationID, out result);
                    e.RespondToClient(ResultConverter.ObjectToBytes(new FromServerPacket(result, content)));
                    e.CloseConnection();
                }
                break;
                }
            };
        }
Beispiel #2
0
        internal ServerCommunicator(int listenPort, int notifyPort, Func <ServerInfo> OnServerInfoRequestReceived, Action OnSendAllNotificationRequestReceived)
        {
            _ListenPort = listenPort;
            _NotifyPort = notifyPort;

            server                   = new TCPServer.TCPServer(_ListenPort);
            _NotifyServer            = new TCPServer.TCPServer(_NotifyPort, true);
            server.OnPacketReceived += (s, e) =>
            {
                System.Diagnostics.Debug.WriteLine("Đã nhận được yêu cầu");
                FromClientPacket ReceivedPacket = null;
                try
                {
                    ReceivedPacket = _FromClientConverter.BytesToObject(e.Data);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("Gói tin bị lỗi khi vận chuyển");
                    e.RespondToClient(_FromServerConverter.ObjectToBytes(new FromServerPacket(FromServerPacketType.DataCorrupted, ex)));
                    return;
                }
                // Giữa 2 server với nhau phải luôn được kết nối, vì vậy khi giao tiếp xong thì vẫn để kết nối đó cho lần tiếp theo
                switch (ReceivedPacket.PacketType)
                {
                case FromClientPacketType.AddNotification:
                {
                    e.RespondToClient(_FromServerConverter.ObjectToBytes(new FromServerPacket(FromServerPacketType.AddNotificationResponse, AddNotification(ReceivedPacket.Data as AddNotificationPacketData)))); break;
                }

                case FromClientPacketType.RequestServerInfo:
                {
                    e.RespondToClient(_FromServerConverter.ObjectToBytes(new FromServerPacket(FromServerPacketType.ServerInfo, OnServerInfoRequestReceived()))); break;
                }

                case FromClientPacketType.SendAllNotification:
                {         // nhận được yêu cầu gửi thì khỏi cần hồi âm
                    OnSendAllNotificationRequestReceived(); break;
                }
                }
            };
        }
        /// <summary>
        /// Gửi một đối tượng dữ liệu bất kì tới WNS
        /// </summary>
        /// <param name="device">Thiết bị cần nhận thông báo, giúp việc xóa thiết bị dễ dàng hơn khi xảy ra lỗi sai URI</param>
        /// <param name="sendobj">Object cần gửi</param>
        /// <param name="devicenoti">Đưa ra việc gửi cho thiết bị nào và gửi thông báo nào, giúp việc xóa nó sẽ dễ dàng hơn nếu gửi thông báo thành công</param>
        public void Send(Device device, T sendobj, DeviceNotification devicenoti)
        {
            bool flag = false;

            byte[] data = Tconverter.ObjectToBytes(sendobj);

            #region chuẩn bị http request và các header phù hợp để gửi raw notification
            HttpWebRequest request = null;
            try
            {
                request = HttpWebRequest.Create(device.URI) as HttpWebRequest;
            }
            catch (Exception ex)
            {
                BadURIErrorOccurred(this, new DelegatesAndEnums.BadURIEventArgs(ex, device));
                return;
            }
            request.Method = "POST";
            request.Headers.Add("X-WNS-Type", "wns/raw");
            request.Headers.Add("X-WNS-Cache-Policy", "cache");
            request.Headers.Add("X-WNS-RequestForStatus", "true");
            request.ContentType = "application/octet-stream";
            request.Headers.Add("Authorization", String.Format("Bearer {0}", token.Token));
            #endregion

            // chuyển đối tượng cần gửi về dạng mảng byte để có thể gửi đi
            #region Gửi Notification
            try
            {
                // gửi yêu cầu có nội dung là mảng byte trên tới uri
                using (Stream requestStream = request.GetRequestStream())
                    requestStream.Write(data, 0, data.Length);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Lỗi xảy ra");
                InternetOrFirewallErrorOccurred(this, ex);
                return;
            }
            #endregion

            #region nhận về Response
            try
            {   // nhận về response
                HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
                SendSuccessed(this, devicenoti);
                System.Diagnostics.Debug.WriteLine(webResponse.Headers["X-WNS-Status"]);
                System.Diagnostics.Debug.WriteLine(webResponse.Headers["X-WNS-DeviceConnectionStatus"]);
                flag = true;
            }
            catch (WebException webException)
            {
                #region Phân tích exception

                // việc gửi yêu cầu bị lỗi không phải do giao thức (các nguyên nhân khác, có thể do mạng hoặc do tường lửa)
                if (webException.Status != WebExceptionStatus.ProtocolError)
                {
                    InternetOrFirewallErrorOccurred(this, webException);
                    return;
                }

                // code chạy xuống dưới đây có nghĩa là lỗi giao thức

                // lấy status code
                HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;

                if (status == HttpStatusCode.Unauthorized) // nếu là lỗi do token hết hạn
                {
                    try
                    {
                        token.RenewToken();
                    }
                    catch (UnauthorizedAccessException uex)
                    {
                        WrongPackageSIDOrSecretKey(this, uex);
                        return;
                    }
                    catch (WebException wex)
                    {
                        InternetOrFirewallErrorOccurred(this, wex);
                        return;
                    }

                    this.Send(device, sendobj, devicenoti);
                }
                else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound || status == HttpStatusCode.Forbidden) // Lỗi phát sinh do URI hết hạn, không tồn tại hoặc sai nên server không được phép gửi tới
                {
                    BadURIErrorOccurred(this, new DelegatesAndEnums.BadURIEventArgs(webException, device));
                    return;
                }
                else if (status == HttpStatusCode.NotAcceptable) // Lỗi do gửi quá nhiều thông báo tới này trong một khoảng thời gian quá ngắn
                {
                    NotAccecptableErrorOccurred(this, webException);
                    return;
                }
                else // Lỗi do một nguyên nhân khác
                {
                    UnknowErrorOccurred(webException, webException);
                    return;
                };
                #endregion
            }
            #endregion
        }