i want to make my android application a server. i have a SocketServerManger class implementing WebSocketServer from “org.java-websocket:Java-WebSocket:1.5.6” liberary.
Java-WebSocket
as i connect to my server with ws connection it works correctly . the problem is when my client wants to connect to it with wss connection .
here is my code :
class SocketServerManger(
port: Int,
val socketListener: List<WebSocketConnectionListener>,
context: Context):WebSocketServer(InetSocketAddress(port)) {
var connection: WebSocket? = null
private val _isConnectionOpen = MutableStateFlow(false)
val isConnectionOpen: StateFlow<Boolean> = _isConnectionOpen
/*this part is added to set ssl context . without this part server works correctly with ws connection*/
init {
createSSLContext(context)?.let {
setWebSocketFactory(DefaultSSLWebSocketServerFactory(it))
}
}
private fun createSSLContext(context: Context): SSLContext? {
try {
val keystoreFileName = "keystore.bks"
val keystorePassword = "password"
val keystoreInputStream: InputStream = context.assets.open(keystoreFileName)
val keyStore = KeyStore.getInstance("BKS")
keyStore.load(keystoreInputStream, keystorePassword.toCharArray())
keystoreInputStream.close()
val keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
keyManagerFactory.init(keyStore, keystorePassword.toCharArray())
val tmf : TrustManagerFactory = TrustManagerFactory.getInstance("BKS");
tmf.init(keyStore)
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, tmf.trustManagers, SecureRandom())
return sslContext
} catch (e: Exception) {
serverLog("createSSLContext ${e.message}")
}
return null
}
/*end of setup ssl*/
override fun onStart() {
serverLog("SocketServerManger onStart")
println("WebSocket server started")
}
override fun onOpen(conn: WebSocket?, handshake: ClientHandshake?) {
connection = conn
socketListener.forEach { it.onConnected() }
}
override fun onClose(conn: WebSocket?, code: Int, reason: String?, remote: Boolean) {
socketListener.forEach { it.onDisconnected(code, reason) }
}
override fun onMessage(conn: WebSocket?, message: String?) {
socketListener.forEach { it.onMessage(conn, message) }
}
override fun onError(conn: WebSocket?, ex: Exception?) {
socketListener.forEach { it.onError(ex) }
ex?.printStackTrace()
}
suspend fun sendMessagesUntilSuccess(timeoutMillis: Long = 50000, message: String): Boolean {
var success = false
while (!success) {
success = sendMessageWithTimeout(timeoutMillis, message)
if (!success) {
// Add a delay before retrying to avoid continuous retries and potential rate limiting
delay(1000)
}
}
return success
}
suspend fun sendMessageWithTimeout(timeoutMillis: Long = 5000, message: String): Boolean {
return withContext(Dispatchers.IO) {
return@withContext try {
withTimeout(timeoutMillis) {
val result = CoroutineScope(Dispatchers.IO).async {
try {
if (connection != null && connection!!.isOpen) {
connection!!.send(message)
true
} else {
false
}
} catch (e: org.java_websocket.exceptions.WebsocketNotConnectedException) {
socketListener.forEach { it.onException(e) }
false
}
}.await()
result
}
} catch (e: TimeoutCancellationException) {
socketListener.forEach { it.onException(e) }
false
} catch (e: Exception) {
socketListener.forEach { it.onException(e) }
false
}
}
}
fun isConnectionOpen() = connection?.isOpen ?: false
fun isPortAvailable(port: Int): Boolean {
return try {
ServerSocket(port).close()
true
} catch (e: IOException) {
false
}
}
}
when i want to connect to the server with web client the connection time outs .