fbonetti / elm-phoenix-socket

Pure Elm state manager for Phoenix channels
MIT License
217 stars 31 forks source link

Inherit host & protocol from endpoint #6

Open simonewebdesign opened 8 years ago

simonewebdesign commented 8 years ago

Hi, we just integrated elm-phoenix-socket yesterday without any issues :)

Is it possible to inherit host and protocol from socketServer? E.g.:

initPhxSocket : Phoenix.Socket.Socket Msg
initPhxSocket =
    let
        socketServer = "ws://localhost:30000/broker/private/websocket?token=123"
    in
        Phoenix.Socket.init socketServer

Would it be possible to omit the first part, so that this would work too:

socketServer = "/broker/private/websocket?token=123"

Phoenix.js does that, and the advantage for us is that we don't need to do any crazy things to change the endpoint depending on the environment.

edevil commented 8 years ago

This would be very useful for us as well. We build containers with our application so we strive to use the same code independently of the environment.

fbonetti commented 8 years ago

This looks pretty straight forward. Can you open a PR?

simonewebdesign commented 8 years ago

Honestly I'm not too sure how to go with this.

As far as I know there's no way to get document.location natively in Elm, and it's not possible to have ports in a package (as the guide says here). So the only way is to use native modules I guess?

I tried the latter approach but I'm still far from a PR, I don't know how I'm supposed to debug/test if it works. Debug.log is not really helpful as it returns <internal structure>.

Any thoughts?

fbonetti commented 8 years ago

Hmm... I originally thought that you could connect a WebSocket with a relative path, but according to this StackOverflow answer, you can only use absolute URLs.

Here's what I think we should do:

  1. Parse socketServer and determine if it's a relative path or an absolute URL
  2. If it's an absolute URL, use it as is
  3. If it's a relative path, combine it with the current location host to form an absolute URL

You can get the current location by using this package: http://package.elm-lang.org/packages/elm-lang/navigation/1.0.0/Navigation

fbonetti commented 8 years ago

Generally speaking, I feel like this is something that should be handled by environment variables instead of the library itself. Determining if the socket server is relative vs absolute will work for some environments, but not for all. For example, your development environment may run on localhost:3000, but in production you have a server that serves the application (myapp.com) and another that handles the API/websockets (api.myapp.com).

Doing this with node and webpack is easy. You can use something like dotenv to load your configuration into environment variables. I don't know if something like this exists for Elm yet.

edevil commented 8 years ago

I wonder why phoenix.js can get away with relative URLs for the websocket (https://github.com/phoenixframework/phoenix/blob/master/web/static/js/phoenix.js#L492). Is it a limitation of Elm's Websocket class?

fbonetti commented 8 years ago

They use a regex to determine if the provided URL is a relative or absolute path. If it's a relative path, they append the location.host, which is what we would need to do as well.

https://github.com/phoenixframework/phoenix/blob/master/web/static/js/phoenix.js#L490-L499

cloud8421 commented 8 years ago

@simonewebdesign Can't you get around this by passing the location as a program flag and keeping the websocket url in the model? See http://package.elm-lang.org/packages/elm-lang/html/1.1.0/Html-App#programWithFlags (hello btw! 👋 )

fbonetti commented 8 years ago

@cloud8421 That's actually not a bad idea. Ideally I'd like this library to mirror the functionality of the phoenix.js library, but integrating the navigation package seems like kind of a pain. Rather than providing for the current path as a subscription, it requires you to use an entirely separate program function.

fbonetti commented 8 years ago

If anyone has an ideas on how to cleanly integrate navigation into this library, please let me know or open a PR.

note89 commented 8 years ago

+1 for this

lessless commented 8 years ago

Is there any progress on the issue folks?

simonewebdesign commented 8 years ago

In our project we use navigation, so we ended up using Location from there.

note89 commented 7 years ago

I don't want to be able to have multiple URLs go to my site. Doing a migration right now, so WebSockets for ahead.life and evryapp.com needs to work for both in the transition period. So i think i need need to determine this at runtime. @simonewebdesign can you provide a bit of info how you did this ?

simonewebdesign commented 7 years ago

@note89 check http://package.elm-lang.org/packages/elm-lang/navigation/1.0.0/Navigation#Location