Code Monkey home page Code Monkey logo

safe-sockets's Introduction

SAFE Template

This template can be used to generate a full-stack web application using the SAFE Stack. It was created using the dotnet SAFE Template. If you want to learn more about the template why not start with the quick start guide?

Install pre-requisites

You'll need to install the following pre-requisites in order to build SAFE applications

  • The .NET Core SDK
  • FAKE 5 installed as a global tool
  • The Yarn package manager (you an also use npm but the usage of yarn is encouraged).
  • Node LTS installed for the front end components.
  • If you're running on OSX or Linux, you'll also need to install Mono.

Work with the application

To concurrently run the server and the client components in watch mode use the following command:

fake build -t Run

SAFE Stack Documentation

You will find more documentation about the used F# components at the following places:

If you want to know more about the full Azure Stack and all of it's components (including Azure) visit the official SAFE documentation.

Troubleshooting

  • fake not found - If you fail to execute fake from command line after installing it as a global tool, you might need to add it to your PATH manually: (e.g. export PATH="$HOME/.dotnet/tools:$PATH" on unix) - related GitHub issue

safe-sockets's People

Contributors

ajwillshire avatar dependabot[bot] avatar isaacabraham avatar tom-sloboda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

safe-sockets's Issues

Connecting from Xamarin

Hi,

I am trying to connect from Xamarin but I am getting a timeout connection error.

Any idea of what is wrong?

I am using System.Net.WebSockets with the following code:

==============================================================================
module WebsocketChannels

open Fable.Remoting.DotnetClient
open System.Threading
open System.Threading.Tasks
open System.Linq
open Shared

type MessageType =
| TextMsg
| ImageMsg
| JsonMsg

type ServerMessage =
{ Time : DateTime
From: Guid option
Type: MessageType
Message : string }

type ClientMessage =
{
ClientId: int option
To: Guid option
Message: string
}

// Add more messages that can go from server -> client here...
type WebSocketServerMessage =
| BroadcastMessage of ServerMessage

// Add more message that can go from client -> server here...
type WebSocketClientMessage =
| TextMessage of ClientMessage
| ImageMessage of ClientMessage

/// Status of the websocket.
type WsSender = WebSocketClientMessage -> unit
//type BroadcastMode = ViaWebSocket | ViaHTTP
type ConnectionState =
| DisconnectedFromServer | ConnectedToServer of WsSender | Connecting
member this.IsConnected =
match this with
| ConnectedToServer _ -> true
| DisconnectedFromServer | Connecting -> false

type Msg =
| ReceivedFromServer of WebSocketServerMessage
| ConnectionChange of ConnectionState
| ConnectionError of exn

module Channel =
open Newtonsoft.Json
open System.Net.WebSockets
open Fabulous
open System

let cts = new CancellationTokenSource()

let inline decode<'a> x = x |> unbox<string> |> JsonConvert.DeserializeObject<'a>
let buildWsSender (ws:WebSocket) : WsSender =
    fun (message:WebSocketClientMessage) ->
        let message = {| Topic = ""; Ref = ""; Payload = message |}
        let message = JsonConvert.SerializeObject(message)
        let byteMessage = System.Text.Encoding.UTF8.GetBytes(message)
        let segmnet = new ArraySegment<byte>(byteMessage)

        ws.SendAsync(segmnet, WebSocketMessageType.Text, true, cts.Token).Wait()

let subscription f _ =
    let sub dispatch =
        let cts = new CancellationTokenSource()
        let mutable ws = new ClientWebSocket()

        /// Continually tries to connect to the server websocket.
        let connect () =
            Task.Factory.StartNew(fun () ->
                while true do
                    try
                        if ws.State <> WebSocketState.Open
                        then ws.ConnectAsync(new Uri("ws://10.0.1.3:8085"), cts.Token).Wait()
                             dispatch (f (ConnectionChange (ConnectedToServer (buildWsSender ws))))

                        let message = new ArraySegment<byte>(Array.zeroCreate 4096)
                        let mutable foo = true
                        while foo do
                            let result = ws.ReceiveAsync(message, cts.Token).Result
                            let messageBytes = message.Skip(message.Offset).Take(result.Count).ToArray()
                            let serialisedMessage = System.Text.Encoding.UTF8.GetString(messageBytes)
                            try
                                let msg = decode<WebSocketServerMessage>(serialisedMessage)
                                dispatch (f (ReceivedFromServer msg))
                                foo <- false
                            with | e -> 
                                dispatch (f (ConnectionError e))
                                Thread.Sleep 5000
                    with e -> dispatch (f (ConnectionError e))
                              ws.Dispose()
                              Console.WriteLine e.StackTrace
                              ws <- new ClientWebSocket()
                              Thread.Sleep 5000
            ,cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default).Start()
        connect()

    Cmd.ofSub sub

Exception Handling: Terminating Sockets

What is the proper way to terminate sockets and catch the exceptions that are thrown when clients improperly terminate a connection by closing the browser tab?

I figured out how to get the socketId in the terminate block of the channel CE, but I was unsure of the proper exception handling and Saturn's Channels documentation is still a bit scarce.

/// Sets up the channel to listen to clients.
let channel = channel {
    join (fun ctx socketId ->
        task {
            ctx.GetLogger().LogInformation("Client has connected. They've been assigned socket Id: {socketId}", socketId)
            return Channels.Ok
        })
    terminate (fun ctx socketId ->
        task {
            ctx.GetLogger().LogInformation("Client (socket Id: {socketId}) has disconnected.", socketId)
        })
}

Screen Shot 2020-05-11 at 15 58 29

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.