rikulo / stomp

STOMP Dart Client for communicating with STOMP-compliant messaging servers.
http://rikulo.org
Other
30 stars 24 forks source link

support stomp over sockjs_dart #11

Open mmly opened 10 years ago

mmly commented 10 years ago

It's really valuable to have support for connection in dart stomp client library over sockjs-dart-client (https://github.com/nelsonsilva/sockjs-dart-client) as it has js-stomp-client library. (eg for websockets apps in Spring4 it's required sockjs, stomp). I don't know how tough task is it, but I believe that existing sock_js_dart library is really helpful for getting this task done. Do you consider/plan to add this feature in near future? I like to help if I could, but I don't understand "low level" websockets stuff (I'm application "higher abstraction level" programmer) however in "higher level" tasks I like to help :)

tomyeh commented 10 years ago

Rikulo Stomp supports WebSocket as well (Example).

There is no plan to support sockjs. However, you can implement your own by implementing StompConnector. You can also refer to _WSStompConnector and SocketStompConnector for implementations.

revelfire commented 10 years ago

I think it would be a benefit to support this if only to mirror the functionality of the javascript equivalents. http://jmesnil.net/stomp-websocket/doc/ In any case here is a wrapped implementation we did to support this, but have not requested it be pushed back. This is a rough cut but it works.

library stomp_websocket;

import "dart:async";

import "package:stomp/stomp.dart" show StompClient;
import "package:stomp/impl/plugin.dart" show StringStompConnector;

import "package:sockjs_client/sockjs.dart" as SockJS;

SockJS.Client _socket;
Future<StompClient> connect(String url, {
        String host, 
        String login, 
        String passcode, 
        List<int> heartbeat,
        List<String> protocolsWhiteList,
        void onDisconnect(),
        void onError(String message, String detail, [Map<String, String> headers]),
        void onConnectionError(error, stacktrace),
        bool debugFlag:false
      }) {
        Future<Object> waitingForConnection = _SockDartConnector.start(url, protocolsWhiteList, debugFlag);

        return waitingForConnection.then((connector){
            // print("Got SockJS/SockDart connection");
            Future<StompClient> waitingForStompClientHolder = StompClient.connect(connector,
                host: host,
                login: login, 
                passcode: passcode, 
                heartbeat: heartbeat,
                onDisconnect: onDisconnect,
                onError: onError).catchError((e) {
                  print(e);
                  onConnectionError(e, e);
                });

            return(waitingForStompClientHolder);    
        });
}

///The implementation
class _SockDartConnector extends StringStompConnector {
  final SockJS.Client _socket;
  Completer<_SockDartConnector> _starting = new Completer();

    static Future<_SockDartConnector> start(String url, List<String> protocolsWhiteList, bool debugFlag) {

      SockJS.Client sockJs = new SockJS.Client(url, protocolsWhitelist:protocolsWhiteList, debug:debugFlag, devel:true);

      _SockDartConnector connector = new _SockDartConnector(sockJs);

      return connector._starting.future;
  }

  _SockDartConnector(this._socket) {
    _init();
  }

  void _init() {
    _socket.onOpen.listen((_) {
      _starting.complete(this);
      _starting = null;
    });
    ///Note: when this method is called, onString/onError/onClose are not set yet
    _socket.onMessage.listen((event) {
      final data = event.data;
      if (data != null) {
        //TODO: handle Blob and TypedData more effectively
        final String sdata = data.toString();
        if (!sdata.isEmpty)
          onString(sdata);
      }
    }, onError: (error, stackTrace) {
      onError(error, stackTrace);
    }, onDone: () {
      //if Socket cannot connect there is no onClose
      if (onClose != null) onClose();
    });
    _socket.onClose.listen((event) {
      if (onClose != null) onClose();
    }); 

  }

  @override
  void writeString_(String string) {
    _socket.send(string);
  }

  @override
  Future close() {
    print("Not sure what to do with close here...close...");
    return new Future.value();
  }
}
revelfire commented 10 years ago

Note my implementation was specifically for integrating with Spring 4 websocket support.

mmly commented 10 years ago

Hallo revelfire, thanks a lot for sharing your implementation. I try this but it looks that there are some problems. I put sample project in github https://github.com/mmly/spring4_stomp_sockjs_dart . There are 2projects:

  1. dart_sockjs_stomp_frontend- there is simple app using your implementation
  2. spring4_sockjs_stomp- official spring 4 websocket sample. It's possible to start this project with gradle bootRun

There was some problems in connection from dart project into spring4 project backend so I compile dart into javascript and put build into spring4 server into: spring4_stomp_sockjs_dart/spring4_sockjs_stomp/complete/src/main/resources/static/build/ then it works at localhost:8080/build/echo.html .It looks that connection stomp through sockjs works but it looks that there is some problem in sending request to server. Server logs shows that spring backend can't map request to java object. I don't know what cause this problem but it looks that problem is in sending message format, because messages looks different between working spring4 implementation using javascript sockjs,stomp and dart version. I check sending frames in chrome dev tools. Because sending isn't working I can't try subscribing.

@revelfire do you test your implementation with spring4, and it works ?

tomikiss commented 10 years ago

Hi,

I found the issue with the request and sent the pull request to your example project. Content type was incorrect that's why Spring cannot map it.

@tomyeh I have a working implementation based on the previous comment for sockjs tested against spring, do you mind if I publish it to pub.dartlang.org depending on your project?

tomyeh commented 10 years ago

@tomikiss No problem.

tomikiss commented 10 years ago

@tomyeh @mmly Added connector to pub as stomp_sockjs using the example codes here. Tested against spring 4 and its working fine.

sdeleuze commented 10 years ago

Awesome, I will test it against our latest Spring 4.1 RC1 release and update my OpenSnap Spring4/Dart sample application !