Skip to content

Commit

Permalink
feat: support for getting connection information; Message.sendId
Browse files Browse the repository at this point in the history
  • Loading branch information
yurizhuk committed Apr 11, 2024
1 parent bdf9a2a commit 0df3a53
Show file tree
Hide file tree
Showing 18 changed files with 265 additions and 94 deletions.
2 changes: 1 addition & 1 deletion mobile-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ afterEvaluate {

groupId = "com.webitel"
artifactId = "mobile-sdk"
version = "0.5.6"
version = "0.6.1"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ internal class WebitelChat(

override fun onNewMessage(message: UpdateNewMessage) {
val dialog = dialogs.firstOrNull { it.id == message.message.chat.id }
val m = createMessageFromResponse(message.message)
val m = createMessageFromResponse(message.id ?: "", message.message)
if (dialog == null) {
createDialogRequest(object : CallbackListener<List<Dialog>> {
override fun onSuccess(t: List<Dialog>) {
Expand All @@ -99,7 +99,10 @@ internal class WebitelChat(
options: Message.options,
callback: MessageCallbackListener
) {
val reqId = UUID.randomUUID().toString()
val sengId = options.sendId
val reqId: String = if(sengId.isNullOrEmpty()) UUID.randomUUID().toString()
else sengId

val message = getMessageFromOptions(reqId, options)

callback.onSend(message)
Expand Down Expand Up @@ -244,7 +247,7 @@ internal class WebitelChat(
callback: MessageCallbackListener
) {
val request = Connect.Request.newBuilder()
.setId(message.reqId)
.setId(message.sendId)
.setPath(ChatMessagesGrpc.getSendMessageMethod().bareMethodName)
.setData(Any.newBuilder().pack(messageRequest))
.build()
Expand All @@ -253,20 +256,10 @@ internal class WebitelChat(

cacheRequests.newRequest(mc)

if (chatApi.isStateReady()) {
sendNextMessageFromQueue()

} else {
chatApi.ping(object : CallbackListener<Unit> {
override fun onSuccess(t: Unit) {
sendNextMessageFromQueue()
}

override fun onError(e: Error) {
cacheRequests.onConnectionError(e)
}
})
if (!chatApi.isStateReady()) {
chatApi.openConnection()
}
sendNextMessageFromQueue()
}


Expand Down Expand Up @@ -300,20 +293,10 @@ internal class WebitelChat(

cacheRequests.newRequest(mc)

if (chatApi.isStateReady()) {
sendRequests()

} else {
chatApi.ping(object : CallbackListener<Unit> {
override fun onSuccess(t: Unit) {
sendRequests()
}

override fun onError(e: Error) {
cacheRequests.onConnectionError(e)
}
})
if (!chatApi.isStateReady()) {
chatApi.openConnection()
}
sendRequests()
}


Expand Down Expand Up @@ -347,20 +330,10 @@ internal class WebitelChat(

cacheRequests.newRequest(mc)

if (chatApi.isStateReady()) {
sendRequests()

} else {
chatApi.ping(object : CallbackListener<Unit> {
override fun onSuccess(t: Unit) {
sendRequests()
}

override fun onError(e: Error) {
cacheRequests.onConnectionError(e)
}
})
if (!chatApi.isStateReady()) {
chatApi.openConnection()
}
sendRequests()
}


Expand Down Expand Up @@ -428,20 +401,10 @@ internal class WebitelChat(

cacheRequests.newRequest(mc)

if (chatApi.isStateReady()) {
sendRequests()

} else {
chatApi.ping(object : CallbackListener<Unit> {
override fun onSuccess(t: Unit) {
sendRequests()
}

override fun onError(e: Error) {
cacheRequests.onConnectionError(e)
}
})
if (!chatApi.isStateReady()) {
chatApi.openConnection()
}
sendRequests()
}


Expand All @@ -450,13 +413,7 @@ internal class WebitelChat(
message: WebitelMessage,
dispo: Messages.Disposition
) {
if (dispo == Messages.Disposition.Incoming) {
dialog.onReceiveNewMessage(message)
} else if (dispo == Messages.Disposition.Outgoing) {
// val lastMessage = dialog.lastMessage
// if (lastMessage == null || (message.id > lastMessage.id))
// dialog.onReceiveNewMessage(message)
}
dialog.onReceiveNewMessage(message)
setTopMessage(dialog, message)
}

Expand Down Expand Up @@ -534,11 +491,11 @@ internal class WebitelChat(
val m = members[(it.from.id.toIntOrNull() ?: 1) - 1]
messages.add(
WebitelMessage(
reqId = null,
sendId = "",
text = it.text,
file = toFile(it.file),
from = m,
isIncoming = session.invoke()?.chatAccount?.id != m.id,
isIncoming = !isCurrentMember(m),
_id = it.id,
_sentAt = it.date
)
Expand Down Expand Up @@ -598,7 +555,7 @@ internal class WebitelChat(

} else {
val message = if (chat.message != null)
createMessageFromResponse(chat.message)
createMessageFromResponse("", chat.message)
else null

val nd = WebitelDialog(
Expand Down Expand Up @@ -635,18 +592,20 @@ internal class WebitelChat(


private fun createMessageFromResponse(
sendId: String,
message: MessageOuterClass.Message
): WebitelMessage {
val m = Member(
id = message.from.id,
name = message.from.name,
type = message.from.type
)
return WebitelMessage(
reqId = null,
sendId = sendId,
text = message.text,
file = toFile(message.file),
from = Member(
id = message.from.id,
name = message.from.name,
type = message.from.type
),
isIncoming = session.invoke()?.chatAccount?.id != message.from.id,
from = m,
isIncoming = !isCurrentMember(m),
_sentAt = message.date,
_id = message.id
)
Expand Down Expand Up @@ -679,7 +638,7 @@ internal class WebitelChat(
o: Message.options
): WebitelMessage {
return WebitelMessage(
reqId = reqId,
sendId = reqId,
text = o.text,
file = if (o.stream == null) null else WebitelFile(
o.fileName ?: UUID.randomUUID().toString(),
Expand Down Expand Up @@ -708,12 +667,17 @@ internal class WebitelChat(
}


private fun isCurrentMember(member: Member): Boolean {
return member.type == "portal" && member.name == "You"
}


private fun getCurrentUser(): Member {
return session.invoke()?.chatAccount
?: Member(
"unknown",
"You",
"user"
"portal"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.webitel.mobile_sdk.domain.Error


internal class WebitelMessage(
val reqId: String?,
override val sendId: String,
override val text: String?,
override val file: WebitelFile?,
override val from: Member,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ internal interface ChatApi: BaseApi {
fun startPing()
fun stopPing()

fun openConnection()

fun uploadFile(
streamObserver: StreamObserver<MessageOuterClass.File>
): StreamObserver<Media.UploadMedia>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ import com.webitel.mobile_sdk.domain.Member
import com.webitel.mobile_sdk.domain.User
import com.webitel.mobile_sdk.domain.CallbackListener
import com.webitel.mobile_sdk.domain.Code
import com.webitel.mobile_sdk.domain.ConnectListener
import com.webitel.mobile_sdk.domain.ConnectState
import com.webitel.mobile_sdk.domain.Error
import com.webitel.mobile_sdk.domain.RegisterResult
import io.grpc.ConnectivityState
import io.grpc.Metadata
import io.grpc.Status
import io.grpc.StatusRuntimeException
import io.grpc.stub.StreamObserver
import webitel.chat.MessageOuterClass
Expand All @@ -41,13 +45,14 @@ import java.util.TimerTask


internal class ClientGrpc(
config: ChannelConfig
) : ChatApi, AuthApi, VoiceApi {
private val config: ChannelConfig
) : ChatApi, AuthApi, VoiceApi, StreamListener {

private var chatListener: GrpcChatMessageListener? = null
private var requestObserver: StreamObserver<Request>? = null
private var timer: Timer? = null
private var channel: GrpcChannel
private lateinit var channel: GrpcChannel
private val connectionListeners = ConnectionListeners()

private val grpcListeners = GrpcListeners()

Expand All @@ -60,9 +65,27 @@ internal class ClientGrpc(
Handler(thread.looper)
}

private var connectState = ConnectState.DISCONNECTED


init {
initChannel()
}


fun addConnectListener(listener: ConnectListener) {
connectionListeners.addListener(listener)
}


fun removeConnectListener(listener: ConnectListener) {
connectionListeners.removeListener(listener)
}


private fun initChannel() {
channel = GrpcUtils.getChannel(config)
channel.setStreamListener(this)
val connectivityStateWatcher = object : Runnable {
override fun run() {
val state = channel.channel.getState(false)
Expand All @@ -74,6 +97,8 @@ internal class ClientGrpc(

ConnectivityState.SHUTDOWN -> {
//Log.e("state", "SHUTDOWN")
channel.setStreamListener(null)
initChannel()
return // DISCONNECTED state is final.
}

Expand All @@ -99,6 +124,7 @@ internal class ClientGrpc(
channel.channel.notifyWhenStateChanged(state, this)
}
}

val state = channel.channel.getState(true)
channel.channel.notifyWhenStateChanged(state, connectivityStateWatcher)
}
Expand Down Expand Up @@ -380,8 +406,15 @@ internal class ClientGrpc(
}


fun openConnection() {
checkAndOpenConnection()
override fun openConnection() {
val state = channel.channel.getState(true)
if (state == ConnectivityState.TRANSIENT_FAILURE) {
channel.channel.resetConnectBackoff()
channel.channel.enterIdle()
checkAndOpenConnection()
} else {
checkAndOpenConnection()
}
}


Expand Down Expand Up @@ -675,6 +708,33 @@ internal class ClientGrpc(

handler.post(job)
}


fun getConnectState(): ConnectState {
return connectState
}


override fun onStart(methodName: String) {
if (methodName != CustomerGrpc.getConnectMethod().bareMethodName) return
connectionListeners.onStateChanged(from = connectState, to = ConnectState.CONNECTING)
connectState = ConnectState.CONNECTING
}


override fun onReady(methodName: String) {
if (methodName != CustomerGrpc.getConnectMethod().bareMethodName) return
connectionListeners.onStateChanged(from = connectState, to = ConnectState.READY)
connectState = ConnectState.READY
}


override fun onClose(methodName: String, status: Status?, trailers: Metadata?) {
if (methodName != CustomerGrpc.getConnectMethod().bareMethodName) return
ConnectState.DISCONNECTED.message = status.toString()
connectionListeners.onStateChanged(from = connectState, to = ConnectState.DISCONNECTED)
connectState = ConnectState.DISCONNECTED
}
}


Loading

0 comments on commit 0df3a53

Please sign in to comment.