Comments (11)
Hey @MarkPare, sorry I can't be more help from the elixir side, but I did not set that portion up. It just worked when I started hitting the endpoint.
from javaphoenixclient.
@dsrees I was never able to solve this and had to opt for a different solution. When I get a chance I'll post something that's reproducible and testable. Thanks.
from javaphoenixclient.
You are trying to connect to a non-ssl endpoint and your application isn't configured to do that. This has nothing to do with this client or even websockets. If you tried to hit a regular REST endpoint on non-ssl localhost the same thing would happen. You should read this.
Heres some excerpts that should help
in AndroidManifest.xml
android:networkSecurityConfig="@xml/network_security_config"
in /res/xml/network_security_config
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
from javaphoenixclient.
Thanks for your response.
Not only that, but I was using an Android emulator which requires using specially-designated port 10.0.2.2 to connect to localhost
on dev machine. It's been a while since I did some Android dev - apologies.
I'm still having an issue connecting. The request is now going through, but I'm getting a 404
and this error in my Android log:
2018-12-15 18:39:58.015 21153-21169/com.mydomain.myapp D/TAG: Transport: error
2018-12-15 18:39:58.018 21153-21169/com.mydomain.myapp W/System.err: java.net.ProtocolException: Expected HTTP 101 response but was '404 Not Found'
2018-12-15 18:39:58.025 21153-21169/com.mydomain.myapp W/System.err: at okhttp3.internal.ws.RealWebSocket.checkResponse(RealWebSocket.java:228)
2018-12-15 18:39:58.026 21153-21169/com.mydomain.myapp W/System.err: at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:195)
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp W/System.err: at java.lang.Thread.run(Thread.java:761)
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp D/Message: Expected HTTP 101 response but was '404 Not Found'
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp D/Response:: Response{protocol=http/1.1, code=404, message=Not Found, url=http://10.0.2.2:4000/socket}
2018-12-15 18:39:58.038 21153-21169/com.mydomain.myapp D/java.net.ProtocolException: Expected HTTP 101 response but was '404 Not Found': "Socket Error"
I can see that the source code for PhxSocket
changes the protocol from ws
to http
, so it makes sense that my phoenix app is returning 404
because there is no http route for /socket
.
Code from PhxSocket
:
// Silently replace web socket URLs with HTTP URLs.
var mutableUrl = url
if (url.regionMatches(0, "ws:", 0, 3, ignoreCase = true)) {
mutableUrl = "http:" + url.substring(3)
} else if (url.regionMatches(0, "wss:", 0, 4, ignoreCase = true)) {
mutableUrl = "https:" + url.substring(4)
}
My javascript phoenix socket client works fine and I don't believe it does anything under the hood to change the protocol - it's always ws
or wss
.
Is there a reason for doing this? Any suggestions are appreciated!
from javaphoenixclient.
The biggest help for debugging would be to create your own okhttp client and log all requests/responses.
in your build.gradle
implementation "com.squareup.okhttp3:logging-interceptor:3.11.0"
create your client
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
httpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()
create your phoenix client
val socket = PhxSocket(baseWsUrl, client = httpClient)
Maybe this will help shed some light on your issue. I can say that this library is working for me, although I did not set up the phoenix backend.
from javaphoenixclient.
Thanks. The error I'm getting makes perfect sense to me. I'm wondering how this could work as my Phoenix backend is expecting a ws
or wss
uri.
For example, my endpoint file is:
defmodule MyAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app
plug CORSPlug, origin: ["*"]
socket "/socket", MyAppWeb.UserSocket
...
so the /socket
uri will only go to MyAppWeb.UserSocket
if it's schema is ws
or wss
; http
or https
will go to my router.ex
.
I don't see anything in the Phoenix app that would automatically give the Expected HTTP 101
response that is expected by this library.
As a side note, I came across this issue in the OkHttp library that is used by this library. I assume this is part of the reason why this library does the silent replacement of ws
schema with http
. However, I still don't understand how this would be expected to work.
Thanks again for your input.
from javaphoenixclient.
Update:
I'm able to open the connection by defining an http route in my router.ex
that matches /socket
uri, then implementing a custom controller function in my Phoenix app that sends the expected response. Something like:
# controller function
def upgrade(conn, _params) do
magic_string = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
client_key = get_req_header(conn, "sec-websocket-key")
r = "#{client_key}#{magic_string}"
r = :crypto.hash(:sha, r)
r = Base.encode64(r)
conn
|> put_resp_header("connection", "Upgrade")
|> put_resp_header("upgrade", "websocket")
|> put_resp_header("Sec-WebSocket-Accept", r)
|> send_resp(101, "")
end
The logic for deriving the Sec-WebSocket-Accept
value is from here.
So now the socket connection is open, but I receive this error almost immediately:
2018-12-16 01:16:49.914 25061-25085/com.mydomain.myapp W/System.err: java.io.EOFException
2018-12-16 01:16:49.914 25061-25085/com.mydomain.myapp W/System.err: at okio.RealBufferedSource.require(RealBufferedSource.java:61)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at okio.RealBufferedSource.readByte(RealBufferedSource.java:74)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.java:117)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.java:101)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.java:274)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:214)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
2018-12-16 01:16:49.915 25061-25085/com.mydomain.myapp W/System.err: at java.lang.Thread.run(Thread.java:761)
Looks like it might be related to this issue from OkHttp library.
The solution proposes adding .pingInterval(30, TimeUnit.SECONDS)
to the client so that server does not close connection.
Still, this doesn't totally explain why I'm seeing this error immediately after socket opening, especially because by default Phoenix websocket shouldn't timeout for at least a minute (at least how I'm reading that document).
from javaphoenixclient.
@dustinconrad, did you need to configure anything in your Phoenix app to get this running? I'm still stuck here. No issues when using Javascript client for Phoenix channels, but no luck with this android client.
from javaphoenixclient.
Hey guys, thanks for trying to work this out together already. I'll try to take some time this weekend to dig a little into this but may be delayed by the holidays!
from javaphoenixclient.
@dsrees , thanks for your response. I'm happy to continue debugging this myself; I'm just kind of stuck right now.
Below are my Elixir and Phoenix versions if that's helpful.
Elixir 1.7.3
Phoenix 1.3.4
from javaphoenixclient.
@MarkPare were you ever able to resolve this? I have not been able to reproduce your issue on my end
from javaphoenixclient.
Related Issues (20)
- NPE in trigger() HOT 4
- Question about the heartbeat HOT 6
- Websocket is automatically reconnected event when intentionally closed HOT 2
- Leaking bindings when the channel reply times out? HOT 3
- Lots of Timers created HOT 2
- ReconnectAfterMs is too big HOT 1
- Downgrade OKhttp to 3.12.2 HOT 1
- Heartbeat seems to be sent only once (instead of every x seconds) HOT 2
- Reconnection strategy documentation HOT 8
- Decoding message payloads HOT 2
- ConcurrentModificationException crash HOT 3
- java.util.ConcurrentModificationException HOT 4
- JSON serialization defaults modify property names HOT 2
- jcenter shutdown - February 2022 HOT 3
- Message.payload marked as non-nullable but can be null HOT 7
- Tries to reconnect with invalid token HOT 3
- Leaving channel causes timeout HOT 5
- `unmatched topic` after reconnect HOT 1
- Issue with AGP v8.0.0 R8 minification HOT 1
- Release 1.1.3 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from javaphoenixclient.