Code Monkey home page Code Monkey logo

scarlet's People

Contributors

aaronweihe avatar akarshsatija avatar aminghadersohi avatar anoop44 avatar ericatplangrid avatar greggiacovelli avatar mhernand40 avatar neilg avatar paolorotolo avatar robelor avatar sgc109 avatar swankjesse avatar tinder-ahe avatar tinder-inakivillar avatar tinder-robolague avatar visheshvadhera avatar xlagunas avatar zhxnlai 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  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  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

scarlet's Issues

Not subscribing to events

Hy im using the 0.1.7 branch from Jitpack.

Currently I have this code and the logs don't display the "socket send event" message.

However I get the message from OkHttp
OkHttp: <-- 101 Switching Protocols https://ws.bitstamp.net/ (147ms)

Which means the handshake was successful, but the connection isn't somehow opened?
I also tried commenting out the filter operator without success.

My subscribe code looks like this:

val event = SocketEventFactory.createEvent() val repo = appRepository.observeWebSocketEvent() .filter { it is WebSocket.Event.OnConnectionOpened<*> } .subscribe({ Timber.i("[app] socket send event:%s", event) appRepository.sendEvent(event) }, { e -> Timber.e(e, "[app] socket error") })

I think theres a lifecycle issue, since when I put the app into background and then go back in, the observer receives events.
I mean to say that even though I subscribe to the socket in onResume() method, it doesn't get initiated and when I put the app in background and then resume again the sockets start working.

java.lang.NullPointerException: subscribeActual failed

Not sure if this a bug in scarlet, in RxJava or just unsupported use case.
Repro steps unknown it is anonymous crash report.

Scarlet usage related to cancelation looks like this:

job = launch {
        fooService.receiveFoo().consumeEach { foo -> //...
  }
}

job may be canceled at anytime.

Scarlet version: 0.1.4
Stacktrace:

java.lang.NullPointerException: subscribeActual failed
       at io.reactivex.Maybe.empty(SourceFile:3732)
       at io.reactivex.internal.operators.maybe.MaybeMap.subscribeActual(SourceFile:40)
       at io.reactivex.Maybe.empty(SourceFile:3727)
       at io.reactivex.internal.operators.maybe.MaybeFilter.subscribeActual(SourceFile:39)
       at io.reactivex.Maybe.empty(SourceFile:3727)
       at io.reactivex.internal.operators.maybe.MaybeMap.subscribeActual(SourceFile:40)
       at io.reactivex.Maybe.empty(SourceFile:3727)
       at io.reactivex.internal.operators.maybe.MaybeFilter.subscribeActual(SourceFile:39)
       at io.reactivex.Maybe.empty(SourceFile:3727)
       at io.reactivex.internal.operators.maybe.MaybeMap.subscribeActual(SourceFile:40)
       at io.reactivex.Maybe.empty(SourceFile:3727)
       at io.reactivex.internal.operators.flowable.FlowableFlatMapMaybe$FlatMapMaybeSubscriber.getOrCreateQueue(SourceFile:132)
       at io.reactivex.internal.operators.flowable.FlowableObserveOn$ObserveOnSubscriber.runAsync(SourceFile:400)
       at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.run(SourceFile:176)
       at io.reactivex.internal.schedulers.ScheduledRunnable.run(SourceFile:61)
       at io.reactivex.internal.schedulers.ScheduledRunnable.call(SourceFile:52)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
       at java.lang.Thread.run(Thread.java:818)

Caused by kotlinx.coroutines.experimental.JobCancellationException: Child job was cancelled because of parent failure


Caused by kotlinx.coroutines.experimental.JobCancellationException: Job was cancelled normally

Runtime errors after adding Scarlet as dependency

Not sure if it's an appropriate place to ask this, but it's always reproducible with Scarlet.

I created a simple empty proejct for Android in the latest Android Studio with Kotlin support. Just a simple hello world application. It worked fine, I only added some test code tp onCreate():

val text = "test string"
val newtext = text.replace("string", "replaced")

Then I simply added Scarlet as dependency as suggested in the README, after doing that the application crashes on android immediately when trying to work with strings (val text = "test string" produces a crash), telling that the java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/text/StringsKt;

If I remove Scarlet from dependencies, it starts working again. What's the problem with it?

buildscript {
    ext.kotlin_version = '1.3.11'
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}
apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    signingConfigs {
    }
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 26
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.1.0-alpha03'
    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
    implementation 'com.github.tinder:scarlet:0.1.7'
}

I may assume that the issue arises from the fact, that the library and my project use slightly different kotlin versions (they're different only in the patch version and should be compatible though), so I'm not sure if it is the problem.

Also there is a warning in Android Studio:

    /home/daniel/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.2.10/85fe1811f3e586d0cc53aba1394d8089f1862215/kotlin-stdlib-jdk8-1.2.10.jar (version 1.2)
    /home/daniel/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.3.0/683e04a4e7f17437d7e1390480f312e122e42e9e/kotlin-stdlib-jdk7-1.3.0.jar (version 1.3)
    /home/daniel/.gradle/caches/transforms-1/files-1.1/kotlin-reflect-1.3.0.jar/1763cf1efecf987258647674f6df6b16/jetified-kotlin-reflect-1.3.0.jar (version 1.3)
    /home/daniel/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.3.0/a134b0cfe9bb44f98b0b3e889cda07923eea9428/kotlin-stdlib-1.3.0.jar (version 1.3)
    /home/daniel/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.3.0/84a2e0288dc17cd64d692eb1e5e0de8cd5ff0846/kotlin-stdlib-common-1.3.0.jar (version 1.3)

Not sure where this jdk8 dependency (version 1.2) comes from.

Reconnection terminates after several attempts

Hi. I found a problem with reconnecting okhttp websockets on 0.1.7/0.2.3-alpha1. After several attempts the reconnection stops.
I think I found a reason. We subscribe on socket event in Connection.open(). But sometimes OkHttpWebSocketEventObserver emit WebSocket.Event.OnConnectionFailed(t) before subscription complete and this event just ignored.
Solution - replace PublishProcessor to BehaviorProcessor.

ConnnectivityOnLifecycle does not close / re-open socket connection

When using Scarlet with OkHttp websocket + AndroidLifecycle with `ofApplicationForeground in the configs, putting the app in the background and bringing back forward closes & re-initiates the connection.

However, turning on/off the airplane mode does not close & re-initiate the socket connection.

MissingBackpressureException: Could not emit value due to lack of requests

Scarlet version: master-SNAPSHOT

Exception in thread "main" io.reactivex.exceptions.MissingBackpressureException: Could not emit value due to lack of requests
	at io.reactivex.processors.PublishProcessor$PublishSubscription.onNext(PublishProcessor.java:365)
	at io.reactivex.processors.PublishProcessor.onNext(PublishProcessor.java:244)
	at com.tinder.scarlet.internal.connection.Connection$StateManager.handleEvent(Connection.kt:176)
	at com.tinder.scarlet.internal.connection.subscriber.WebSocketEventSubscriber.onNext(WebSocketEventSubscriber.kt:16)
	at com.tinder.scarlet.internal.connection.subscriber.WebSocketEventSubscriber.onNext(WebSocketEventSubscriber.kt:12)
	at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(FlowableMap.java:69)
	at io.reactivex.internal.operators.flowable.FlowableObserveOn$ObserveOnSubscriber.runAsync(FlowableObserveOn.java:400)
	at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.run(FlowableObserveOn.java:176)
	at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
	at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

MissingBackpressureException: Could not emit value due to lack of requests

Repro steps unkown, issue from crash report.
Scarlet version: 0.1.4

Fatal Exception: MissingBackpressureException: Could not emit value due to lack of requests
       at io.reactivex.processors.PublishProcessor$PublishSubscription.onError(SourceFile:319)
       at io.reactivex.processors.PublishProcessor.onNext(SourceFile:197)
       at com.tinder.scarlet.internal.connection.Connection$StateManager.access$scheduleRetry(SourceFile:163)
       at com.tinder.scarlet.internal.connection.subscriber.WebSocketEventSubscriber.onError(SourceFile:16)
       at com.tinder.scarlet.internal.connection.subscriber.WebSocketEventSubscriber.onNext(SourceFile:12)
       at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(SourceFile:69)
       at io.reactivex.internal.operators.flowable.FlowableObserveOn$ObserveOnSubscriber.runAsync(SourceFile:400)
       at io.reactivex.internal.operators.flowable.FlowableObserveOn$BaseObserveOnSubscriber.run(SourceFile:176)
       at io.reactivex.internal.schedulers.ScheduledRunnable.run(SourceFile:61)
       at io.reactivex.internal.schedulers.ScheduledRunnable.call(SourceFile:52)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
       at java.lang.Thread.run(Thread.java:764)

Connection reconnects constantly instead of sending ping

I've started using Scarlet this week and I've noticed that the WebSocket connection fails and a new one is started every minute or so. Is there an easy way to keep the connection open by sending a ping instead of re-connecting every time?

I'm using version 0.1.7.

Typo in versioning

The latest version name is misspelt as apha instead of alpha. Also, it should be alpha5.
screen shot 2018-11-05 at 7 43 28 pm

Unable to close the connection

Hi, I was wandering whether it is possible to close the connection on purpose. Is it?

e.g. by pressing a button to stop receiving stuff?

Make APIs user-friendly

Hello.
Can you please explain me, wtf is going on here?

val scarletBuilder = Scarlet.Configuration(
    streamAdapterFactories = listOf(CoroutinesStreamAdapterFactory()),
    debug = true
)

val protocol = object : Protocol {
    override fun createChannelFactory(): Channel.Factory = object : Channel.Factory {
        override fun create(listener: Channel.Listener, parent: Channel?): Channel? = parent
    }

    override fun createEventAdapterFactory(): ProtocolSpecificEventAdapter.Factory {
        TODO: fill this
    }
}

val scarlet = Scarlet(protocol, scarletBuilder)

Is this a new way to create a Scarlet instance, really?
If yes - where is documentation? Wtf is ProtocolSpecificEventAdapter? Why i need ChannelFactory?

How to use dynamic path like Retrofit?

My case is open WSocket with domain: abcd.xyz/admin

  • 1 endpoint to handshake with server.
  • 1 endpoint to subcribe one event.

So how to use dynamic path like Retrofit or must change base WS url?
Many thanks!

Proguard rules?

I tried to use scarlet (0.16 and 0.17) and I having an issue when proguard is enabled.
Are there any specific rules for that?

Update coroutine adapter to stable version

Kotlin is already at version 1.3.0 and therefore coroutines are not experimental anymore.
This update also implied a change at package level of the coroutine classes leaving the experimentalnamespace.

On the other hand, looking at CoroutinesStreamAdapterFactoryclass, particularly at:

override fun create(type: Type): StreamAdapter<Any, Any> {
        return when (type.getRawType()) {
            ReceiveChannel::class.java -> ReceiveChannelStreamAdapter()
            else -> throw IllegalArgumentException()
        }
    }

there's a mismatch between the old package and the current one, causing an IllegalArgumentException()

Fix should be quite easy, update kotlin version to 1.3.0 and change the package imports to the new ones.

Is it possible to use this in a Java project?

I have added this project to my pom.xml in a regular Java application.

However I'm getting the following error

"Missing artifact androidx.appcompat:appcompat:jar:1.0.0"

Is it not possible to use this in a regular Java program? if so how?

Http client headers support

Hi
Don't works headers for okhttp3 client, that uses for scarlet config builds.
I need to add user token in headers, but nothing happens
It's also don't displays in logs.
Can you explain this issue? Thanks
ver 0.1.7

cannot access OkHttpWebSocket constructor and other errors

Hi,
Using version 0.2.1-alpha4 I cannot compile sample code:

val protocol = OkHttpWebSocket(
            client,
            OkHttpWebSocket.SimpleRequestFactory(
                { Request.Builder().url("wss://ws-feed.gdax.com").build() },
                { ShutdownReason.GRACEFUL }
            )
        )

OkHttpWebSocket constructor is internal and it doesn't have a SimpleRequestFactory method, also constructor doesn't accept parameter types used in the sample.

Thanks.

How to subscribe to a topic or send message to different endpoint with same Scarlet Instance

Hi, I'm trying to communicate with a STOMP server with my Android APP. There is an issue about that, but it is closed and not so much helpful.
For example how can I subscribe to a topic with the same Scarlet/Service instance? How to Send a message to an other subEndpoint?

It will be very useful for example extend the annotations @receive and @send to append a different endpoint like STOMP Spring Server can offer.

Thanks

OkHttpClientUtils

What about extensions and utils from sample?

OkHttpClient.newWebSocketFactory(...)

java.lang.IllegalStateException: Service method not found when using Koin

I am trying to use Scarlet with Koin but everytime I acces the Service instance from the dependency graph, Scarlet throws an java.lang.IllegalStateException: Service method not found Exception.

Here is how the Dependency definition looks like

val networkingModule = module {
    single { createOkHttpClient() }
    single { createScarlet(get(), "ws://demos.kaazing.com/echo") }
    single { createEchoService(get()) }
}


fun createOkHttpClient(): OkHttpClient = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        .build()

fun createScarlet(client: OkHttpClient, url: String) = Scarlet.Builder()
        .webSocketFactory(client.newWebSocketFactory(url))
        .addMessageAdapterFactory(MoshiMessageAdapter.Factory())
        .addStreamAdapterFactory(CoroutinesStreamAdapterFactory())
        .build()

fun createEchoService(scarlet: Scarlet): EchoService = scarlet.create()

And this is how you would end up calling it (in this example Activity):

class MainActivity : AppCompatActivity() {

    val service: EchoService by inject() //lazy!

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        service.observeEvents()
    }
}

Injecting the Scarlet Instance and creating the service in the activity however would work:

class MainActivity : AppCompatActivity() {

    val scarlet: Scarlet by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        val service: EchoService = scarlet.create()
        service.observeEvents()
    }
}

The only Problem with the workaround is that I would need to create new instances of the service everywhere I need it. Of course I could setup a holder pattern or something but that would defeat the purpose of using DI.

Here is the full stacktrace:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sample.scarlet/com.sample.scarlet.MainActivity}: java.lang.IllegalStateException: Service method not found
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.IllegalStateException: Service method not found
        at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor.execute(ServiceMethodExecutor.kt:18)
        at com.tinder.scarlet.internal.Service.execute(Service.kt:18)
        at com.tinder.scarlet.Scarlet$createInvocationHandler$1.invoke(Scarlet.kt:123)
        at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
        at $Proxy2.toString(Unknown Source)
        at java.lang.String.valueOf(String.java:2896)
        at java.lang.StringBuilder.append(StringBuilder.java:132)
        at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$1.invoke(InstanceRegistry.kt:112)
        at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$1.invoke(InstanceRegistry.kt:36)
        at org.koin.core.stack.ResolutionStack.resolve(ResolutionStack.kt:44)
        at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:105)
        at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:36)
        at org.koin.core.time.DurationKt.measureDuration(Duration.kt:8)
        at org.koin.core.instance.InstanceRegistry.proceedResolution(InstanceRegistry.kt:84)
        at org.koin.core.instance.InstanceRegistry.resolve(InstanceRegistry.kt:63)
        at org.koin.core.instance.InstanceRegistry.resolve$default(InstanceRegistry.kt:48)
        at com.sample.scarlet.MainActivity$$special$$inlined$inject$1.invoke(ComponentCallbacksExt.kt:148)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at com.sample.scarlet.MainActivity.getService(Unknown Source:7)
        at com.sample.scarlet.MainActivity.onCreate(MainActivity.kt:19)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

With default lifecycle config, SocketIoClient is not connecting

If I do not specify lifecycle for Scarlet.Configuration, SocketIoClient is not connecting.

My dagger module which creates Scarlet

@Module
class MykModule {
    @Singleton
    @Provides
    fun provideScarletConfiguration(app: Application): Scarlet.Configuration {
        return Scarlet.Configuration(
            lifecycle = AndroidLifecycle.ofApplicationForeground(app), // With out this, Scarlet is not connectin
            messageAdapterFactories = listOf(MoshiMessageAdapter.Factory()),
            streamAdapterFactories = listOf(RxJava2StreamAdapterFactory()),
            )
    }

    @Singleton
    @Provides
    fun provideScarlet(config: Scarlet.Configuration): Scarlet {
        val client = SocketIoClient({ "https://my.api" })
        return Scarlet(client, config)
    }

    @Singleton
    @Provides
    fun provideMyApi(scarlet: Scarlet): MyApi {
        return scarlet.create<MyApi>()
    }

    @Singleton
    @Provides
    fun providePingTopic(scarlet: Scarlet, config: Scarlet.Configuration): PingTopic {
        return scarlet.child(SocketIoEventName("ping"), config).create<PingTopic>()
    }
}

I try to keep my connection alive even when the app is in background, so I can not use lifecycle AndroidLifecycle.ofApplicationForeground(app)

Im using Scarlet 0.2.1-alpha4

One time urls? Disable reconnecting?

Hi, my backend generates a wss:// url for me, which however is a one time thing, meaning upon connetion lost, I wont be able to reconnect, which is what Im seeing with Scarlet, (infinite loop of WaitingToRetry, Connecting)

Is there way to disable the reconnecting policy and Ill maybe handle connecting back manually? Since I need to call backend api again to generate a new wss:// url

Thanks

cannot resolve stream adapter for kotlin coroutines

Hi,
The same code using RxJava stream adapter works fine.

val scarlet = Scarlet.Builder().webSocketFactory(client.newWebSocketFactory(SOCKET_URL))
            .lifecycle(lifecycle)
            .addMessageAdapterFactory(GsonMessageAdapter.Factory())
            .addStreamAdapterFactory(CoroutinesStreamAdapterFactory()).build()
return scarlet.create()
interface CashCoolSocketService {
    @Receive
    fun observeUser(): ReceiveChannel<UserSerializer>
}
GlobalScope.launch(CoroutineExceptionHandler { _, throwable ->
            Log.e(
                "SOCKET ERROR",
                throwable.message
            )
        }) {
            val user = ws.observeUser().receive()
            Log.d("SOCKET MESSAGE", user.toString())
        }
Throws following error: E/AndroidRuntime: FATAL EXCEPTION: main Process: app.cashcool.cashcool, PID: 3109 java.lang.IllegalStateException: Cannot resolve stream adapter for type kotlinx.coroutines.channels.ReceiveChannel. at com.tinder.scarlet.internal.servicemethod.StreamAdapterResolver.resolve(StreamAdapterResolver.kt:26) at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.createStreamAdapter(ServiceMethod.kt:89) at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:81) at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:66) at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.toServiceMethod(ServiceMethodExecutor.kt:47) at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.findServiceMethods(ServiceMethodExecutor.kt:38) at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.create(ServiceMethodExecutor.kt:32) at com.tinder.scarlet.internal.Service$Factory.create(Service.kt:28) at com.tinder.scarlet.Scarlet.implementService(Scarlet.kt:108) at com.tinder.scarlet.Scarlet.create(Scarlet.kt:100) at app.cashcool.cashcool.core.di.ApplicationModule.provideCashCoolSocketService(ApplicationModule.kt:109) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.proxyProvideCashCoolSocketService(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:55) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.provideInstance(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:41) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.get(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:34) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.get(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:11) at dagger.internal.DoubleCheck.get(DoubleCheck.java:47) at app.cashcool.cashcool.core.di.DaggerApplicationComponent.injectCreateUserFragment(DaggerApplicationComponent.java:328) at app.cashcool.cashcool.core.di.DaggerApplicationComponent.inject(DaggerApplicationComponent.java:288) at app.cashcool.cashcool.features.user.create.CreateUserFragment.onCreate(CreateUserFragment.kt:109) at androidx.fragment.app.Fragment.performCreate(Fragment.java:2414) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:844) at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1196) at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1079) at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:118) at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1844) at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1802) at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1709) at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManagerImpl.java:147) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) Caused by: io.reactivex.exceptions.CompositeException: 2 exceptions occurred. at com.tinder.scarlet.internal.servicemethod.StreamAdapterResolver.resolve(StreamAdapterResolver.kt:25) at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.createStreamAdapter(ServiceMethod.kt:89)  at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:81)  at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:66)  at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.toServiceMethod(ServiceMethodExecutor.kt:47)  at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.findServiceMethods(ServiceMethodExecutor.kt:38)  at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.create(ServiceMethodExecutor.kt:32)  at com.tinder.scarlet.internal.Service$Factory.create(Service.kt:28)  at com.tinder.scarlet.Scarlet.implementService(Scarlet.kt:108)  at com.tinder.scarlet.Scarlet.create(Scarlet.kt:100)  at app.cashcool.cashcool.core.di.ApplicationModule.provideCashCoolSocketService(ApplicationModule.kt:109)  at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.proxyProvideCashCoolSocketService(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:55)  at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.provideInstance(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:41)  at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.get(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:34)  at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.get(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:11)  at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)  at app.cashcool.cashcool.core.di.DaggerApplicationComponent.injectCreateUserFragment(DaggerApplicationComponent.java:328)  at app.cashcool.cashcool.core.di.DaggerApplicationComponent.inject(DaggerApplicationComponent.java:288)  at app.cashcool.cashcool.features.user.create.CreateUserFragment.onCreate(CreateUserFragment.kt:109)  at androidx.fragment.app.Fragment.performCreate(Fragment.java:2414)  at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:844)  at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1196)  at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1079)  at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:118)  at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1844)  at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1802)  at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1709)  at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManagerImpl.java:147)  at android.os.Handler.handleCallback(Handler.java:789)  at android.os.Handler.dispatchMessage(Handler.java:98)  at android.os.Looper.loop(Looper.java:164)  at android.app.ActivityThread.main(ActivityThread.java:6541)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)  Caused by: io.reactivex.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received => at android.util.Log.printlns(Log.java:417) E/AndroidRuntime: at com.android.internal.os.RuntimeInit.Clog_e(RuntimeInit.java:60) at com.android.internal.os.RuntimeInit.-wrap0(Unknown Source:0) at com.android.internal.os.RuntimeInit$LoggingHandler.uncaughtException(RuntimeInit.java:89) at java.lang.Thread.dispatchUncaughtException(Thread.java:1948) Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lkotlinx/coroutines/experimental/channels/ReceiveChannel; at com.tinder.streamadapter.coroutines.CoroutinesStreamAdapterFactory.create(CoroutinesStreamAdapterFactory.kt:19) at com.tinder.scarlet.internal.servicemethod.StreamAdapterResolver.resolve(StreamAdapterResolver.kt:19) at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.createStreamAdapter(ServiceMethod.kt:89) at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:81) at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:66) at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.toServiceMethod(ServiceMethodExecutor.kt:47) at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.findServiceMethods(ServiceMethodExecutor.kt:38) at com.tinder.scarlet.internal.servicemethod.ServiceMethodExecutor$Factory.create(ServiceMethodExecutor.kt:32) at com.tinder.scarlet.internal.Service$Factory.create(Service.kt:28) at com.tinder.scarlet.Scarlet.implementService(Scarlet.kt:108) at com.tinder.scarlet.Scarlet.create(Scarlet.kt:100) at app.cashcool.cashcool.core.di.ApplicationModule.provideCashCoolSocketService(ApplicationModule.kt:109) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.proxyProvideCashCoolSocketService(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:55) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.provideInstance(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:41) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.get(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:34) at app.cashcool.cashcool.core.di.ApplicationModule_ProvideCashCoolSocketServiceFactory.get(ApplicationModule_ProvideCashCoolSocketServiceFactory.java:11) at dagger.internal.DoubleCheck.get(DoubleCheck.java:47) at app.cashcool.cashcool.core.di.DaggerApplicationComponent.injectCreateUserFragment(DaggerApplicationComponent.java:328) at app.cashcool.cashcool.core.di.DaggerApplicationComponent.inject(DaggerApplicationComponent.java:288) at app.cashcool.cashcool.features.user.create.CreateUserFragment.onCreate(CreateUserFragment.kt:109) at androidx.fragment.app.Fragment.performCreate(Fragment.java:2414) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:844) at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1196) at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1079) at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:118) at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1844) at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1802) at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1709) at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManagerImpl.java:147) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) E/AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlinx.coroutines.experimental.channels.ReceiveChannel" on path: DexPathList[[zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/base.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_dependencies_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_resources_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_0_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_1_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_2_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_3_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_4_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_5_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_6_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_7_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_8_apk.apk", zip file "/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/lib/x86, /system/lib, /system/vendor/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 36 more Suppressed: java.io.IOException: No original dex files found for dex location /data/app/app.cashcool.cashcool-Szw56xvjCrKy9lGGtl4lKg==/split_lib_resources_apk.apk at dalvik.system.DexFile.openDexFileNative(Native Method) at dalvik.system.DexFile.openDexFile(DexFile.java:353) at dalvik.system.DexFile.(DexFile.java:100) at dalvik.system.DexFile.(DexFile.java:74) at dalvik.system.DexPathList.loadDexFile(DexPathList.java:374) at dalvik.system.DexPathList.makeDexElements(DexPathList.java:337) at dalvik.system.DexPathList.(DexPathList.java:157) at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:65) at dalvik.system.PathClassLoader.(PathClassLoader.java:64) at com.android.internal.os.PathClassLoaderFactory.createClassLoader(PathClassLoaderFactory.java:43) at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:69) at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:36) at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:676) at android.app.LoadedApk.getClassLoader(LoadedApk.java:709) at android.app.LoadedApk.getResources(LoadedApk.java:936) at android.app.ContextImpl.createAppContext(ContextImpl.java:2242) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5672) at android.app.ActivityThread.-wrap1(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1661) at android.os.Handler.dispatchMessage(Handler.java:105) ... 5 more

Obsolete documentation

The current documentation for 0.2.x is obsolete. Some classes are not present anymore. Example WebSocketEvent .

SocketIO compatibility?

I'm trying to emulate socket.emit with this library and I'm not really sure how to do that? Is communicating with a SocketIO server supported?

Kotlin Coroutine adapter

Any plans to introduce a StreamAdapter for Kotlin coroutines ? Maybe returning a ReceiveChannel ?

Thanks

STOMP Compatibility

The standard for websocket communication is often regarded as being STOMP. Does this / will this library have STOMP compatibility in its message layer?

Scarlet in Java/Android

Hi, I'm having trouble integrating Scarlet into my Android app written in Java. Can you provide an example please (maybe put it in the Readme section along with the Kotlin example)?

Retry policy doesn't take the AndroidLifecycle into account

I have a Scarlet instance inside a Android LifecycleService which has been started in foreground, in order for the service to not be destroyed when the application is not in foreground anymore. I've set the Scarlet lifecycle owner as the LifecycleService in which it resides.

I'm trying to start the Scarlet instance, but it fails (404 not found), hence the BackoffStrategy kicks in, which works as expected. However, if I kill the service (its onDestroy is called), the Scarlet instance continues to retry connecting to the server. I expected it to die along with the service.

Unfortunately, no WebSocket event is being called, thus I don't have access to the WebSocket object and I cannot close it when the service gets destroyed:

disposables += webSocketService.observeOnConnectionEvent().subscribe { when (it) { is WebSocket.Event.OnConnectionOpened<*> -> { Log.i(TAG, "Web socket opened") webSocket = it.webSocket as WebSocket } is WebSocket.Event.OnConnectionClosing -> Log.i(TAG, "Web socket closing") is WebSocket.Event.OnConnectionClosed -> Log.i(TAG, "Web socket closed") is WebSocket.Event.OnConnectionFailed -> Log.e(TAG, "Web socket failed", it.throwable) is WebSocket.Event.OnMessageReceived -> Log.i(TAG, "Web socket message received $it.message") } }

Hi,i encountered this error shown below...,i cant figure it out

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':app:transformClassesWithDexForFreeDebug'.

com.android.build.api.transform.TransformException: java.lang.RuntimeException: java.lang.RuntimeException: Unable to pre-dex 'C:\Users\mike.gradle\caches\modules-2\files-2.1\com.github.tinder.scarlet\scarlet-core\0.1.4\b5366480d19f19212823e2f7a42f0664bc878daa\scarlet-core-0.1.4.jar' to 'D:\AndroidStudioProjects\android-juli\app\build\intermediates\transforms\dex\free\debug\folders\1000\10\scarlet-core-0.1.4_d0e9a0649fe7c644f8281caa71c5828931a34219'

How to add token in header ?

In retrofit, we can embed @HeaderMap and @fieldmap in case of POST or @QueryMap in case of GET. This way we can embed an authorized token in the header and pass by parameters either in GET or as a form in POST. My question, how can we achieve a similar thing in scarlet to pass by authorization token to the server?

How to subscribe to similar entities

v. 0.2.1-alpha4
There is a basic entity of the socket response that differs in the content of the data field and the value of the endpoint field. For example. First is a payment structure:

{
  "endpoint": "updates.payments", 
  "data": {
    "payments": [
      {
        "payment_status": "success",
        //...other fields...
        "currency": {
          "decimal_places": 2,
          "currency_code": "GBP",
          "currency_name": "UK Sterling"
        }
      }
    ]
  }
}

And message structure:

{
  "endpoint": "updates.messages", 
  "data": {
    "messages": [
      {
        "message_status": "send_success",
        //other fields
        "text":"blah blag blah"
      }
    ]
  }
}

In SocketInterface i have next code:

interface SocketInterface {

    @Receive
    fun subscribeToMessages(): Flowable<PushMessage<MessagesData>>

    @Receive
    fun subscribeToPayments(): Flowable<PushMessage<PaymentData>>
}

And PushMessage model see this:

data class PushMessage<T>(
        @SerializedName("endpoint") val method: String,
        @SerializedName("data") val data: T
)

data class MessagesData(
        @SerializedName("messages") val messages: List<ChatMessage>
)

data class PaymentData(
        @SerializedName("payments") val payments: List<BaseTransactionNet>
)

By subscribing to both events, I receive two events if I receive one of them.
Is there any way to fix it?

Can't load all modules

My build.gradle top lvl:

buildscript {
    ext.kotlin_version = '1.3.11'
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle app lvl:

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.ng.exttest3"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.github.tinder.scarlet:scarlet:0.2.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

it looks absolutely standard, but many modules not load. I see only scarlet, carlet-core, scarlet-core-internal, scarlet-message-adapter, scarlet-stream-adapter. In older dependency versions (kotlin, gradle plugin and other) i catch other error - #50

And please, move it to maven central or other great place for libraries

Question

Hi, thanks for the library. I have question regarding to how did you handle such state transition:
App Opened -> App Sent to background -> App came to foreground (all in a second)

Is it:
connecting -> disconnecting -> connecting ? Do you queue states or just immediately transition to next state by cancelling, or restarting okHttp calls?

Method return type must not include a type variable or wildcard

I'm getting the following error:
IllegalArgumentException: Method return type must not include a type variable or wildcard: io.reactivex.Flowable<com.tinder.scarlet.WebSocket$Event$OnConnectionOpened<?>>
at
@Receive fun observeOnConnectionOpenedEvent(): Flowable<WebSocket.Event.OnConnectionOpened<*>>

fun <T> create(service: Class<T>): T { val clientBuilder = OkHttpClient.Builder() clientBuilder.addInterceptor(AuthInterceptor() val scarlet = Scarlet.Builder() .webSocketFactory(clientBuilder.build().newWebSocketFactory(ApiEndPoint.WEBSOCKET)) .addMessageAdapterFactory(GsonMessageAdapter.Factory()) .addStreamAdapterFactory(RxJava2StreamAdapterFactory()) .build() return scarlet.create(service) }

val websocketApi = BaseScarletBuilder.create(WebsocketApi::class.java)

Is this the way we are suppose to use the lib?

Library broke kotlinx.android.synthetic

After adding the library, all android extension methods are broken. And i see demo in 0.2.x version - why you not use kotlin-android-extensions?
Looks like you know something...

0.1.x: Lifecycle compilation error

com.android.builder.multidex.D8MainDexList$MainDexListException: 
com.android.tools.r8.errors.CompilationError: 
Program type already present: com.tinder.scarlet.lifecycle.android.BuildConfig

Multiple @Receive annotated methods called for the same Message

I've got multiple methods annotated with @ Receive inside Scarlet's interface. The problem is that, for example, when a Route is sent on the socket from the server, all 4 observable callbacks are being called, instead of only the observeRoute() one. What can be causing this and why? I mean, I can get why the observeRoute() and observeOnConnectionEvent() callbacks are called; but why are the other 2 called which have nothing to do with the connection or the Route model?

 @Receive
    fun observeOnConnectionEvent(): Flowable<WebSocket.Event>
    
    @Receive
    fun observeAlerts(): Flowable<Alert>
    
    @Receive
    fun observeRoute(): Flowable<Route>
    
    @Receive
    fun observeVehicle(): Flowable<Vehicle>

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.