Inheritance: IStreamWebSocket, IWebSocket, IClosable
        /// <summary>
        /// WindowsStoreApp Implementation
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        /// 
        /// 
//        private StreamWebSocket _streamWebSocket;
//
//        private StreamWebSocket _streamWebSocketServer;

        public object CreateWebSocketClientObject()
        {
            StreamWebSocket webSocket =  new StreamWebSocket();
            //_streamWebSocket = webSocket;
            //webSocket.Closed += Closed;
            return webSocket;
        }
Example #2
0
 private async void InitializeSocket()
 {
     try
     {
         StreamWebSocket webSocket = streamWebSocket;
         if (webSocket == null)
         {
             Uri server;
             if(!Uri.TryCreate("ws://192.168.0.2", UriKind.Absolute, out server)) // działa tylko u mnie albo jak bedziesz podłączony do serwera
             {
                 return;
             }
             webSocket = new StreamWebSocket();
             webSocket.Closed += Closed;
             await webSocket.ConnectAsync(server);
             streamWebSocket = webSocket;
             readBuffer = new byte[6000000];
             Task recieving = Task.Factory.StartNew(ReceiveData, webSocket.InputStream.AsStreamForRead(), TaskCreationOptions.LongRunning);
             Task sending = Task.Factory.StartNew(SendData, webSocket.OutputStream, TaskCreationOptions.LongRunning);
         }
     }
     catch(Exception ex)
     {
         WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);
     }
 }
        public void Reset()
        {
            lock (this)
            {
                if (readPacket != null)
                {
                    try
                    {
                        readPacket.DetachStream();
                        readPacket = null;
                    }
                    catch (Exception exp)
                    {
                        Diag.DebugPrint("Could not detach DataReader: " + exp.Message);
                    }
                }

                if (writePacket != null)
                {
                    try
                    {
                        writePacket.DetachStream();
                        writePacket = null;
                    }
                    catch (Exception exp)
                    {
                        Diag.DebugPrint("Could not detach DataWriter: " + exp.Message);
                    }
                }

                if (socket != null)
                {
                    socket.Dispose();
                    socket = null;
                }

                if (channel != null)
                {
                    if (((IDictionary<string, object>)CoreApplication.Properties).ContainsKey(channel.ControlChannelTriggerId))
                    {
                        CoreApplication.Properties.Remove(channel.ControlChannelTriggerId);
                    }

                    // Call the Dispose() method on the controlchanneltrigger object to release any 
                    // OS maintained resources for this channel object. 
                    channel.Dispose();
                    channel = null;
                }
                Diag.DebugPrint("CommModule has been reset.");
            }
        }
Example #4
0
        public async Task ConnectAsync(Address address)
        {
            StreamWebSocket sws = new StreamWebSocket();
            sws.Control.SupportedProtocols.Add(WebSocketSubProtocol);
            sws.Closed += this.OnWebSocketClosed;

            Uri uri = new UriBuilder()
            {
                Scheme = address.Scheme,
                Port = GetDefaultPort(address.Scheme, address.Port),
                Host = address.Host,
                Path = address.Path
            }.Uri;

            await sws.ConnectAsync(uri);

            this.webSocket = sws;
        }
        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (streamWebSocket != null)
                {
                    rootPage.NotifyUser("Stopping", NotifyType.StatusMessage);
                    streamWebSocket.Close(1000, "Closed due to user request.");
                    streamWebSocket = null;
                }
                else
                {
                    rootPage.NotifyUser("There is no active socket to stop.", NotifyType.StatusMessage);
                }
            }
            catch (Exception ex)
            {
                WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);

                if (status == WebErrorStatus.Unknown)
                {
                    throw;
                }

                // Normally we'd use the status to test for specific conditions we want to handle specially,
                // and only use ex.Message for display purposes.  In this sample, we'll just output the
                // status for debugging here, but still use ex.Message below.
                rootPage.NotifyUser("Error: " + status, NotifyType.ErrorMessage);

                OutputField.Text += ex.Message + "\r\n";
            }
        }
 public AppContext(CommModule commInstance, StreamWebSocket webSocket, ControlChannelTrigger channel, string id)
 {
     WebSocketHandle = webSocket;
     Channel = channel;
     ChannelId = id;
     CommInstance = commInstance;
     messageQueue = new ConcurrentQueue<string>();
 }
        public bool SetupTransport(string serviceUri)
        {
            bool result = false;
            lock (this)
            {
                // Save these to help reconnect later.
                serverUri = serviceUri;

                // Set up the ControlChannelTrigger with the stream socket.
                result = RegisterWithControlChannelTrigger(serverUri);
                if (result == false)
                {
                    Diag.DebugPrint("Failed to sign on and connect");
                    if (socket != null)
                    {
                        socket.Dispose();
                        socket = null;
                        readPacket = null;
                    }
                    if (channel != null)
                    {
                        channel.Dispose();
                        channel = null;
                    }
                }
            }
            return result;
        }
        async Task<bool> RegisterWithCCTHelper(string serverUri)
        {
            bool result = false;
            socket = new StreamWebSocket();

            // Specify the keepalive interval expected by the server for this app
            // in order of minutes.
            const int serverKeepAliveInterval = 30;

            // Specify the channelId string to differentiate this
            // channel instance from any other channel instance.
            // When background task fires, the channel object is provided
            // as context and the channel id can be used to adapt the behavior
            // of the app as required.
            const string channelId = "channelOne";

            // IMPORTANT: Note that this is a websocket sample, therefore the 
            // keepalive task class is provided by Windows for websockets. 
            // For websockets, the system does the keepalive on behalf of the
            // app but the app still needs to specify this well known keepalive task.
            // This should be done here in the background registration as well 
            // as in the package manifest.
            const string WebSocketKeepAliveTask = "Windows.Networking.Sockets.WebSocketKeepAlive";

            // Try creating the controlchanneltrigger if this has not been already 
            // created and stored in the property bag.
            Diag.DebugPrint("RegisterWithCCTHelper Starting...");
            ControlChannelTriggerStatus status;
            Diag.DebugPrint("Create ControlChannelTrigger ...");

            // Create the ControlChannelTrigger object and request a hardware slot for this app.
            // If the app is not on LockScreen, then the ControlChannelTrigger constructor will 
            // fail right away.
            try
            {
                channel = new ControlChannelTrigger(channelId, serverKeepAliveInterval,
                                   ControlChannelTriggerResourceType.RequestHardwareSlot);
            }
            catch (UnauthorizedAccessException exp)
            {
                Diag.DebugPrint("Please add the app to the lock screen." + exp.Message);
                return result;
            }

            Uri serverUriInstance;
            try
            {
                serverUriInstance = new Uri(serverUri);
            }
            catch (Exception exp)
            {
                Diag.DebugPrint("Error creating URI: " + exp.Message);
                return result;
            }

            // Register the apps background task with the trigger for keepalive.
            var keepAliveBuilder = new BackgroundTaskBuilder();
            keepAliveBuilder.Name = "KeepaliveTaskForChannelOne";
            keepAliveBuilder.TaskEntryPoint = WebSocketKeepAliveTask;
            keepAliveBuilder.SetTrigger(channel.KeepAliveTrigger);
            keepAliveBuilder.Register();

            // Register the apps background task with the trigger for push notification task.
            var pushNotifyBuilder = new BackgroundTaskBuilder();
            pushNotifyBuilder.Name = "PushNotificationTaskForChannelOne";
            pushNotifyBuilder.TaskEntryPoint = "BackgroundTaskHelper.PushNotifyTask";
            pushNotifyBuilder.SetTrigger(channel.PushNotificationTrigger);
            pushNotifyBuilder.Register();

            // Tie the transport method to the ControlChannelTrigger object to push enable it.
            // Note that if the transport's TCP connection is broken at a later point of time,
            // the ControlChannelTrigger object can be reused to plug in a new transport by
            // calling UsingTransport API again.
            Diag.DebugPrint("Calling UsingTransport() ...");
            try
            {

                channel.UsingTransport(socket);

                // Connect the socket
                //
                // If connect fails or times out it will throw exception.
                await socket.ConnectAsync(serverUriInstance);

                Diag.DebugPrint("Connected");

                // Call WaitForPushEnabled API to make sure the TCP connection has 
                // been established, which will mean that the OS will have allocated 
                // any hardware slot for this TCP connection.
                //
                // In this sample, the ControlChannelTrigger object was created by 
                // explicitly requesting a hardware slot.
                //
                // On Non-AOAC systems, if app requests hardware slot as above, 
                // the system will fallback to a software slot automatically.
                //
                // On AOAC systems, if no hardware slot is available, then app 
                // can request a software slot [by re-creating the ControlChannelTrigger object].
                status = channel.WaitForPushEnabled();
                Diag.DebugPrint("WaitForPushEnabled() completed with status: " + status);
                if (status != ControlChannelTriggerStatus.HardwareSlotAllocated
                    && status != ControlChannelTriggerStatus.SoftwareSlotAllocated)
                {
                    throw new Exception(string.Format("Neither hardware nor software slot could be allocated. ChannelStatus is {0}", status.ToString()));
                }

                // Store the objects created in the property bag for later use.
                // NOTE: make sure these objects are free threaded. STA/Both objects can 
                // cause deadlocks when foreground threads are suspended.
                CoreApplication.Properties.Remove(channel.ControlChannelTriggerId);

                var appContext = new AppContext(this, socket, channel, channel.ControlChannelTriggerId);
                ((IDictionary<string, object>)CoreApplication.Properties).Add(channel.ControlChannelTriggerId, appContext);
                result = true;
                Diag.DebugPrint("RegisterWithCCTHelper Completed.");

                // Almost done. Post a read since we are using streamwebsocket
                // to allow push notifications to be received.
                PostSocketRead(MAX_BUFFER_LENGTH);
            }
            catch (Exception exp)
            {
                Diag.DebugPrint("RegisterWithCCTHelper Task failed with: " + exp.Message);

                // Exceptions may be thrown for example if the application has not 
                // registered the background task class id for using real time communications 
                // broker in the package appx manifest.
            }
            return result;
        }
        private async Task StartAsync()
        {
            // Validating the URI is required since it was received from an untrusted source (user input).
            // The URI is validated by calling TryGetUri() that will return 'false' for strings that are not
            // valid WebSocket URIs.
            // Note that when enabling the text box users may provide URIs to machines on the intrAnet
            // or intErnet. In these cases the app requires the "Home or Work Networking" or
            // "Internet (Client)" capability respectively.
            Uri server = rootPage.TryGetUri(ServerAddressField.Text);
            if (server == null)
            {
                return;
            }

            streamWebSocket = new StreamWebSocket();
            streamWebSocket.Closed += OnClosed;

            // If we are connecting to wss:// endpoint, by default, the OS performs validation of
            // the server certificate based on well-known trusted CAs. We can perform additional custom
            // validation if needed.
            if (SecureWebSocketCheckBox.IsChecked == true)
            {
                // WARNING: Only test applications should ignore SSL errors.
                // In real applications, ignoring server certificate errors can lead to Man-In-The-Middle
                // attacks. (Although the connection is secure, the server is not authenticated.)
                // Note that not all certificate validation errors can be ignored.
                // In this case, we are ignoring these errors since the certificate assigned to the localhost
                // URI is self-signed and has subject name = fabrikam.com
                streamWebSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
                streamWebSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);

                // Add event handler to listen to the ServerCustomValidationRequested event. This enables performing
                // custom validation of the server certificate. The event handler must implement the desired
                // custom certificate validation logic.
                streamWebSocket.ServerCustomValidationRequested += OnServerCustomValidationRequested;

                // Certificate validation is meaningful only for secure connections.
                if (server.Scheme != "wss")
                {
                    AppendOutputLine("Note: Certificate validation is performed only for the wss: scheme.");
                }
            }

            AppendOutputLine($"Connecting to {server}...");
            try
            {
                await streamWebSocket.ConnectAsync(server);
            }
            catch (Exception ex) // For debugging
            {
                streamWebSocket.Dispose();
                streamWebSocket = null;

                AppendOutputLine(MainPage.BuildWebSocketError(ex));
                AppendOutputLine(ex.Message);
                return;
            }
            rootPage.NotifyUser("Connected", NotifyType.StatusMessage);

            // Start a task to continuously read for incoming data
            Task receiving = ReceiveDataAsync(streamWebSocket);

            // Start a task to continuously write outgoing data
            Task sending = SendDataAsync(streamWebSocket);
        }
 private void CloseSocket()
 {
     if (streamWebSocket != null)
     {
         try
         {
             streamWebSocket.Close(1000, "Closed due to user request.");
         }
         catch (Exception ex)
         {
             AppendOutputLine(MainPage.BuildWebSocketError(ex));
             AppendOutputLine(ex.Message);
         }
         streamWebSocket = null;
     }
 }
        // Continuously read incoming data. For reading data we'll show how to use activeSocket.InputStream.AsStream()
        // to get a .NET stream. Alternatively you could call readBuffer.AsBuffer() to use IBuffer with
        // activeSocket.InputStream.ReadAsync.
        private async Task ReceiveDataAsync(StreamWebSocket activeSocket)
        {
            Stream readStream = streamWebSocket.InputStream.AsStreamForRead();
            int bytesReceived = 0;
            try
            {
                AppendOutputLine("Background read starting.");

                byte[] readBuffer = new byte[1000];

                while (true)
                {
                    if (streamWebSocket != activeSocket)
                    {
                        // Our socket is no longer active. Stop reading.
                        AppendOutputLine("Background read stopped.");
                        return;
                    }

                    int read = await readStream.ReadAsync(readBuffer, 0, readBuffer.Length);

                    // Do something with the data.
                    // This sample merely reports that the data was received.

                    bytesReceived += read;
                    DataReceivedField.Text = bytesReceived.ToString();
                }
            }
            catch (Exception ex)
            {
                WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);

                switch (status)
                {
                    case WebErrorStatus.OperationCanceled:
                        AppendOutputLine("Background read canceled.");
                        break;

                    default:
                        AppendOutputLine("Error: " + status);
                        AppendOutputLine(ex.Message);
                        break;
                }
            }
        }
        // Continuously write outgoing data. For writing data we'll show how to use data.AsBuffer() to get an
        // IBuffer for use with activeSocket.OutputStream.WriteAsync.  Alternatively you can call
        // activeSocket.OutputStream.AsStreamForWrite() to use .NET streams.
        private async Task SendDataAsync(StreamWebSocket activeSocket)
        {
            int bytesSent = 0;
            byte[] data = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };

            AppendOutputLine($"Background sending data in {data.Length} byte chunks each second.");

            try
            {
                // Send until the socket gets closed/stopped
                while (true)
                {
                    if (streamWebSocket != activeSocket)
                    {
                        // Our socket is no longer active. Stop sending.
                        AppendOutputLine("Background write stopped.");
                        return;
                    }

                    await activeSocket.OutputStream.WriteAsync(data.AsBuffer());

                    bytesSent += data.Length;
                    DataSentField.Text = bytesSent.ToString();

                    // Delay so the user can watch what's going on.
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }
            }
            catch (Exception ex)
            {
                WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);

                switch (status)
                {
                    case WebErrorStatus.OperationCanceled:
                        AppendOutputLine("Background write canceled.");
                        break;

                    default:
                        AppendOutputLine("Error: " + status);
                        AppendOutputLine(ex.Message);
                        break;
                }
            }
        }
        private async void OnServerCustomValidationRequested(StreamWebSocket sender, WebSocketServerCustomValidationRequestedEventArgs args)
        {
            // In order to call async APIs in this handler, you must first take a deferral and then
            // release it once you are done with the operation. The "using" statement
            // ensures that the deferral completes when control leaves the block.
            bool isValid;
            using (Deferral deferral = args.GetDeferral())
            {
                // Get the server certificate and certificate chain from the args parameter.
                isValid = await MainPage.AreCertificateAndCertChainValidAsync(args.ServerCertificate, args.ServerIntermediateCertificates);

                if (!isValid)
                {
                    args.Reject();
                }
            }

            // Continue on the UI thread so we can update UI.
            var task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                if (isValid)
                {
                    AppendOutputLine("Custom validation of server certificate passed.");
                }
                else
                {
                    AppendOutputLine("Custom validation of server certificate failed.");
                }
            });
        }
        // This may be triggered remotely by the server or locally by Close/Dispose()
        private void Closed(IWebSocket sender, WebSocketClosedEventArgs args)
        {
            MarshalText(OutputField, "Closed; Code: " + args.Code + ", Reason: " + args.Reason + "\r\n");

            if (streamWebSocket != null)
            {
                streamWebSocket.Dispose();
                streamWebSocket = null;
            }
        }
 public StreamWebSocketEvents(StreamWebSocket This)
 {
     this.This = This;
 }
        private async void Start_Click(object sender, RoutedEventArgs e)
        {
            // Have we connected yet?
            if (streamWebSocket != null)
            {
                rootPage.NotifyUser("Already connected", NotifyType.StatusMessage);
                return;
            }

            // Validating the URI is required since it was received from an untrusted source (user input).
            // The URI is validated by calling TryGetUri() that will return 'false' for strings that are not
            // valid WebSocket URIs.
            // Note that when enabling the text box users may provide URIs to machines on the intrAnet
            // or intErnet. In these cases the app requires the "Home or Work Networking" or
            // "Internet (Client)" capability respectively.
            Uri server;
            if (!rootPage.TryGetUri(ServerAddressField.Text, out server))
            {
                return;
            }

            try
            {
                rootPage.NotifyUser("Connecting to: " + server, NotifyType.StatusMessage);

                streamWebSocket = new StreamWebSocket();

                // Dispatch close event on UI thread. This allows us to avoid synchronizing access to streamWebSocket.
                streamWebSocket.Closed += async (senderSocket, args) =>
                {
                    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Closed(senderSocket, args));
                };

                await streamWebSocket.ConnectAsync(server);

                readBuffer = new byte[1000];

                // Start a background task to continuously read for incoming data
                Task receiving = Task.Factory.StartNew(Scenario2ReceiveData,
                    streamWebSocket.InputStream.AsStreamForRead(), TaskCreationOptions.LongRunning);

                // Start a background task to continuously write outgoing data
                Task sending = Task.Factory.StartNew(Scenario2SendData,
                    streamWebSocket.OutputStream, TaskCreationOptions.LongRunning);

                rootPage.NotifyUser("Connected", NotifyType.StatusMessage);
            }
            catch (Exception ex) // For debugging
            {
                if (streamWebSocket != null)
                {
                    streamWebSocket.Dispose();
                    streamWebSocket = null;
                }

                WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);

                switch (status)
                {
                    case WebErrorStatus.CannotConnect:
                    case WebErrorStatus.NotFound:
                    case WebErrorStatus.RequestTimeout:
                        rootPage.NotifyUser("Cannot connect to the server. Please make sure " +
                            "to run the server setup script before running the sample.", NotifyType.ErrorMessage);
                        break;

                    case WebErrorStatus.Unknown:
                        throw;

                    default:
                        rootPage.NotifyUser("Error: " + status, NotifyType.ErrorMessage);
                        break;
                }

                OutputField.Text += ex.Message + "\r\n";
            }
        }
Example #17
0
 public WebSocketTransport(StreamWebSocket webSocket)
 {
     this.webSocket = webSocket;
 }