vukoye / xmpp_dart

Lightweight XMPP client library written in Dart
Apache License 2.0
83 stars 64 forks source link

WebSocket support #67

Open eye-dee opened 2 years ago

eye-dee commented 2 years ago

Hello, As far as I can see the library doesn't have websocket support Are there any plans to do so?

TatankaConCube commented 2 years ago

it already has support for WebSocket, try version 0.4.2-dev.1), it works well in our project

eye-dee commented 2 years ago

Thank you, works fine!

The only thing I needed to change is a possibility to specify url path for web socket connection:

class XmppWebSocketHtml:


 _socket = WebSocketChannel.connect(
      Uri(
        scheme: 'wss',
        host: host,
        port: port,
        path: 'xmpp-websocket' <-------------- Path here
      ),
      protocols: ['xmpp'],
    );
eldhomt commented 2 years ago

@sausageRoll I tried your suggestion. It is giving the following error:

[log] ---Xmpp Receiving:---
[log] <stream:error xmlns:stream="http://etherx.jabber.o…ietf:params:xml:ns:xmpp-streams"/></stream:error>
[log] ---Xmpp Receiving:---
[log] <close xmlns='urn:ietf:params:xml:ns:xmpp-framing'/>
[log] D/[Connection]: Handle connection done
[log] D/[Connection]: State: XmppConnectionState.ForcefullyClosed
[log] D/[ReconnectionManager]: Connection forcefully closed!
[log] D/[ReconnectionManager]: TimeOut is: 2000 reconnection counter 0
eye-dee commented 2 years ago

@eldhomt The path is different for different servers. Most of the time users should be able to connect without it. But we have a specific deployment and it requires path in URI:

wss://host:port/xmpp-websocket

If that's what you tried My suggestion would be exposing that path as a configuration parameter similar to host and port

eldhomt commented 2 years ago

@sausageRoll Yes, I have a used a different path. In my case the schema is wsand path is ws://host:port/ws and I am using openfire server. I have tested the same with React web application and is working fine.

eye-dee commented 2 years ago

@eldhomt Make sure you use WebSocket implementation, because there are two different implementations for sockets.

import 'connection/XmppWebsocketApi.dart'
  if (dart.library.io) 'connection/XmppWebsocketIo.dart'
  if (dart.library.html) 'connection/XmppWebsocketHtml.dart' as xmppSocket;

I had to change it to:

import 'connection/XmppWebsocketHtml.dart' as xmppSocket;
eldhomt commented 2 years ago

@sausageRoll No Luck. I am getting the same error. Few others have reported the same issue at https://github.com/vukoye/xmpp_dart/issues/71.

szotp commented 2 years ago

According to the spec communication with web socket should start with something like this

<open xmlns="urn:ietf:params:xml:ns:xmpp-framing" to="example.com" version="1.0" />

but nothing like that exists in this repository.

Sad to be saying this, but this library is completely unusable in its current state (at least if you want web sockets).

  1. The example code is wrong or obsolete.
  2. There are no version tags.
  3. This class makes no sense, it's regular socket pretenting to be a web socket.
  4. You can't connect with Url.
  5. Web socket doesn't even connect properly
codesxt commented 2 years ago

I could not make it work by just changing the URI parsing process as the first comments suggested. When I checked ejabberd logs, the server was receiving my requests but throwing this error:

2022-04-25 10:47:32.143 [error] <0.2316.0>@xmpp_socket:parse:422 CRASH REPORT Process <0.2316.0> with 0 neighbours exited with reason: bad argument in call to fxml_stream:parse(undefined, <<"<?xml version='1.0'?><stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://et...">>) in xmpp_socket:parse/2 line 422

So I thought that the error should be somewhere else and checked @szotp 's answer. I checked RFC-3975 section 3.4 and changed the streamOpeningString variable and it worked, instead of the stream:stream opening string that works on regular sockets.

So maybe there should be a condition to select the proper stream opening stream according to the specific socket type. I wrote this condition to make it work for both sockets:

void _openStream() {
    var streamOpeningString =
        (_socket.runtimeType.toString() == 'XmppWebSocketHtml')
            ? """
<open xmlns="urn:ietf:params:xml:ns:xmpp-framing"
             to='${fullJid.domain}'
             version="1.0" />
"""
            : """
<?xml version='1.0'?>
<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams'
to='${fullJid.domain}'
xml:lang='en'
>
""";
    write(streamOpeningString);
  }
eldhomt commented 2 years ago

@codesxt Thanks. That fixes the issue. Working fine with all the platforms now.

TatankaConCube commented 2 years ago

today we released a new version 0.4.4-dev.1 with fixes and requirements from this thread

HaoCherHong commented 1 year ago

today we released a new version 0.4.4-dev.1 with fixes and requirements from this thread

@TatankaConCube Does this branch supports web?

TatankaConCube commented 1 year ago

yes, sure, but the latest version, for now, is 0.4.4-dev.3