GithubHelp home page GithubHelp logo

elm-lang / websocket Goto Github PK

View Code? Open in Web Editor NEW
99.0 99.0 30.0 28 KB

Websockets for Elm

Home Page: http://package.elm-lang.org/packages/elm-lang/websocket/latest

License: BSD 3-Clause "New" or "Revised" License

websocket's People

Contributors

evancz avatar process-bot avatar simonh1000 avatar thomasweiser avatar vyp avatar

Stargazers

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

Watchers

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

websocket's Issues

This is completely broken in current elm?

Er sooooo.

Elm 0.19 is out. The elm guide is entirely examples from 0.19. But this package is both broken from the package manager (websocket 1.0.2 just wont install at all), and, even cooler, throws a pretty bracing error at the compiler level if you try to vendor it:

Creating `effect` modules is relatively experimental. There are a couple in @elm
repos right now, but we have decided to be very cautious in expanding its usage.

Get rid of all the effect stuff in WebSocket to proceed.

Note: You can learn the reasoning behind this design choice at
<https://elm-lang.org/0.19.0/effect-modules>

My favorite part about this error is that the link "explaining" it 404s.

So uh. What... what now?

Support binary websockets?

I'd like to send protobuf messages over a websocket, but the only interface that WebSocket exposes is String-based.

Support sending ordered list of messages

In some case we have to send several messages in the socket at once, but in a specific order, which cannot be guaranteed by using several Cmd.

I can see 2 possible APIs for that:

  • add a specific function:

    sendMany : List (String) -> Cmd msg
  • add a task-based API:

    sendTask : String -> Task Error ()

Multiple open connections when subscription changes quickly

To reproduce this issue, try the SSCCE that follows and double click on the Toggle button a couple of times. You should see multiple open/pending connections in Chrome's Network tab. If you allow some delay between clicks, connections get closed properly.

I have tried this on macOS version 10.12.5 using Chrome version 58.0.3029.110 and Chrome Canary version 61.0.3132.0.

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import WebSocket


main =
  Html.program
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions
    }


echoServer : String
echoServer =
  "wss://echo.websocket.org"


type alias Model = Bool


init : (Model, Cmd Msg)
init =
  (True, Cmd.none)


type Msg
  = NewMessage String
  | Toggle


update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Toggle ->
      (not model, Cmd.none)
    _ ->
      (model, Cmd.none)


subscriptions : Model -> Sub Msg
subscriptions model =
  if model
     then WebSocket.listen echoServer NewMessage
     else Sub.none


view : Model -> Html Msg
view model =
  div [] [ button [onClick Toggle] [text "Toggle"] ]

API is missing notification of reconnect thus unnecessarily limiting its utility

The Problem

Websockets are stateful conversations. When this library auto-reconnects, it doesn't tell anyone it's done so. The server just thinks it has a new connection unrelated to the previous on-going conversation. The client isn't given a chance to remind the server who it is and, in fact, has no idea that it's having an entirely different conversation as far as the server is concerned. It's a little like invasion of the body snatchers, tbh.

The Problem re: Phoenix

When you attempt to use this WebSocket module with phoenix, the phoenix server stores all the conversation's state, including what channels that have been joined, in the phoenix server's representation of the socket. When a reconnect happens, the new socket has none of that state. From the client's perspective, it's as if it's been dropped from all the channels but with no notification that that's happened. All messages from the server to the client come over channels, so the client will no longer get any messages and not even know that it needs to start waving its arms around wildly to get the server's attention.

I know there is a specific problem with phoenix, but I think the same problem would exist with any websocket approach as, again, it's a stateful conversation we're talking about.

The solution

The solution is fairly simple. This library should notify its clients upon reconnect. This will give the client a chance to tell the server who it is and that it needs a full dump of any missing state.

Not the solution

One might be able to cobble something together by sending a periodic "Here I am Identity Heartbeat" type message to the server that would let the server say "Wait! That's you! No way! You're way behind!" However, since that effectively is a poll it would need to be at some interval and during the interval the client might be woefully out of date. Depending on what you're doing, it might be okay. It's obviously not great though and kind of undermines the websocket thing for a lot of applications.

Not the solution either

I also don't think the solution is "just use the WebSocket.LowLevel stuff". That's not the solution because the fix is pretty easy and w/o the fix, sadly, I think the WebSocket module's use is fairly limited -- at least limited to applications that don't mind an occasional unrecoverable failure that manifests as...what was I saying. Also, there's a lot of complicated code in WebSocket.elm (thank you!) and it's really close to being quite useful for a wide set of purposes even with a low surface area API.

Exponential backoff does not work

Elm Version: 0.18
OS: Mac OS X
Browser: Chrome
SSCCE:

Because this is a bug internal to the websocket library, it can't be illustrated in an isolated example. Here are the simplest steps to reproduce:

  • Make a local copy of the echo example
  • Manually edit Websocket.elm in the elm-stuff/packages/websocket/1.0.2 directory. Add log statements to this line and this line so that you can see when they are fired.
  • Change the echoServer uri to something bogus to trigger reconnect behavior and run the application
  • Check the console and notice that the debug statement on this line is never executed, which is responsible for incrementing the connect attempt count that the backoff strategy is dependent on.

Detailed description:

The BadOpen message is never dispatched, presumably because the Die message is dispatched with every failed connect attempt. This appears to be happening because the native websocket onClose handler is fired every failed connect attempt, and then onSelfMsg handles the Die message, resetting the connection state.

It appears that the browser itself does some sort of connection throttling, which may be why this issue has gone unnoticed.

Bug in 0.17 alpha - Websocket.listen in Child Component loses the appropriate Msg Tagging erratic results

When I call WebSocket.listen from within the outermost parent (Main.elm for example), thing seem to work as expected, however when I call WebSocket.listen on child components (Component.elm) I get erratic results. In particular the Msg aren't properly tagged and pattern matching in the update function doesn't work properly..

In the later scenario (WebSocket.listen called from Component.elm), the first Message Received from the Server is properly returned, however subsequent messages lose the appropriate Msg tagging which screws up pattern matching and passing Component.Msg down...

Here's an example repo with a simple Parent & Child Component and a minimal Websocket Server (in nodejs).
If you download the repo and follow steps in the README.md, you'll see what's happening.
https://github.com/knowthen/elm-websocket-bug-rpt

Here's a short video demo of the bug:
Bug

Provide some way of checking for support

Not all browsers support websockets - it would be great to know if websockets are actually supported in the browser used, so you can fall back on something else.
As far as I can tell, there is currently no way to check this.

Perhaps a command isSupported or fail an open with a new BadOpen?

Bug in 0.17 alpha - Calling Websocket.send in Http.App.program's init doesn't work, the WebSocket message is never sent

Background: I'm writing an app where a websocket message is sent on initial page load requesting data from the server

Issue: calling WebSocket.send in Http.App.program's init doesn't work. Message seems to be lost.

init : (Model, Cmd Msg)
init =
  -- Looking at chrome dev tools, this string is never sent
  (Model "" "", WebSocket.send url "hello first time" )

Speculation: Seems to be either a timing issue waiting on the websocket to connect, or not properly queuing and sending the message after connected, or potentially some sort of runtime problem like this issue: https://github.com/elm-lang/core/issues/582

Calling WebSocket.send in update from a UI triggered Msg does work.

Here's the code: https://gist.github.com/knowthen/9348d4eda390139a82de91dc75167eab

Here's a quick demo showing the initial message isn't sent (on page load)
Then when I click the button, the message is sent and echoed back.

alt text

Error being swallowed when trying to open a websocket with a `#` character in its url

While building an Elm app connecting to a Phoenix channel, I was using tokens that contained # characters in them. As I naively thought they were just a plain string I wasn't uri encoding it before adding it to the query parameters of the socket url.

There is a DOMException when attempting to do new WebSocket(url) and it is being swallowed, is there a way to surface this error?

screen shot 2016-07-04 at 2 58 13 am

Add subscriptions for connection opened and connection closed.

I believe this would solve #10

There are a number of reasons we would want to know when a connection is established or closed:

Hypothetical not-well-vetted API:

type RetryInfo
     = NoRetry     -- Will not attempt to re-establish the connection
     | RetryIn Int -- Will attempt to re-establish the connection in the specified number of seconds

type alias ConnectionClosedHandler msg 
    = String    -- Connection URI
   -> Int       -- CloseEvent code
   -> RetryInfo -- Retry information
   -> msg

connectionClosed : ConnectionClosedHandler -> Sub msg

connectionOpened : (String -> msg) -> Sub msg

I wouldn't mind taking a stab at implementing this, assuming I can get some feedback on the proposed API.

Internal server error when downloading 1.0.2 release

When I try to install the package as well as when trying to download the zip for the release I get a 500 error, I was able to install it a while after this but I still dont know the reason it failed in the first place so it may be something to look into.
Although this is probably just a problem with the repo, im using ubuntu 16.04 and elm 0.18

Websocket exponential backoff is not randomized

Websocket reconnect attempts should be spaced out randomly, to spread out any spikes that might have caused the outage in the first place. Otherwise you'll just overload the server again every 2^c seconds.

Ethernet uses a random backoff between 0 and 2^c-1, and we should do something similar.

Support Authorization header

I am trying to pass my user credentials to my websocket server using the url ws://username:[email protected]. Unfortunately on the server side I don't see any Authorization header.

I initially thought about an old chromium issue but I have the exact same issue on FIrefox.

It would be very nice to support HTTP basic auth during upgrade request or even better, allow us to pass additional headers (maybe in the low level API).

Elm 0.19 release

It would be nice to be able to use websocket connections with 0.19, since I found no way to just use the master branch of a repo in Elm.

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.