Skip to content

Commit

Permalink
moving read operations to a new thread and selector
Browse files Browse the repository at this point in the history
  • Loading branch information
zsiegel committed Mar 18, 2018
1 parent 3b0dd3f commit 18308cc
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 11 deletions.
7 changes: 6 additions & 1 deletion src/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,10 @@ import java.nio.charset.StandardCharsets
fun main(args: Array<String>) {
val socket = Socket("localhost", 10301)
val input = socket.getOutputStream()
input.write("Hello Server".toByteArray(StandardCharsets.UTF_8))
input.write(("Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer messageHello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message " +
"Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer messageHello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message " +
"Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer messageHello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message " +
"Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer messageHello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message " +
"Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer messageHello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message " +
"Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer messageHello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message Hello Server this is a longer message ").toByteArray(StandardCharsets.UTF_8))
}
25 changes: 15 additions & 10 deletions src/Server.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ fun main(args: Array<String>) {
val server = Server(10301)

val serverThread = Thread(server)
serverThread.name = "NIO Server Acceptor"
Runtime.getRuntime().addShutdownHook(Thread {
serverThread.interrupt()
})
Expand All @@ -20,17 +21,24 @@ class Server(port: Int) : Runnable {
val socketChannel: ServerSocketChannel = ServerSocketChannel.open()
val selector: Selector

val readerThread: Thread
val serverReader: ServerReader = ServerReader()

init {
socketChannel.socket().bind(InetSocketAddress(port))
socketChannel.configureBlocking(false)

selector = Selector.open()
socketChannel.register(selector, SelectionKey.OP_ACCEPT)

readerThread = Thread(serverReader)
readerThread.name = "NIO Server Reader"
readerThread.start()
}

override fun run() {

println("Server socket listening on ${socketChannel.socket().localPort}")
println("[${Thread.currentThread().name}] - Server socket listening on ${socketChannel.socket().localPort}")

try {

Expand All @@ -45,21 +53,18 @@ class Server(port: Int) : Runnable {
accept(key)
}

if (key.isReadable) {
val clientId = key.attachment() as String

}

iter.remove()
}
}

println("Socket closing gracefully")
println("[${Thread.currentThread().name}] - Socket closing gracefully")
socketChannel.close()

} catch (e: IOException) {
System.err.println("Closing down socket - ${e.printStackTrace()}")
System.err.println("[${Thread.currentThread().name}] - Closing down socket - ${e.printStackTrace()}")
}

readerThread.interrupt()
}

private fun accept(selectionKey: SelectionKey) {
Expand All @@ -69,9 +74,9 @@ class Server(port: Int) : Runnable {
clientSocket.configureBlocking(false)

val address = clientSocket.socket().inetAddress.toString()
val port = clientSocket.socket().localPort
val port = clientSocket.socket().port
val clientId = "$address:$port"

clientSocket.register(selector, SelectionKey.OP_READ, clientId)
clientSocket.register(serverReader.selector, SelectionKey.OP_READ, clientId)
}
}
50 changes: 50 additions & 0 deletions src/ServerReader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import java.nio.ByteBuffer
import java.nio.channels.SelectionKey
import java.nio.channels.Selector
import java.nio.channels.SocketChannel
import java.nio.charset.StandardCharsets

class ServerReader : Runnable {

val selector: Selector = Selector.open()

override fun run() {

println("[${Thread.currentThread().name}] - Server reader thread is now running")
while (!Thread.interrupted()) {

selector.select(1000)

val iter = selector.selectedKeys().iterator()
iter.forEach { key ->

if (key.isReadable) {
read(key)
}

iter.remove()
}
}

println("[${Thread.currentThread().name}] - Server reader thread stopping")
}

private fun read(selectionKey: SelectionKey) {
val clientId = selectionKey.attachment() as String

val socket = selectionKey.channel() as SocketChannel

//We know this is more than what we are sending - we will deal with multiple buffers later
val buffer = ByteBuffer.allocate(512)

val bytesRead = socket.read(buffer)
if (bytesRead > 0) {
println("---- [${Thread.currentThread().name}] - Reading from $clientId")

println("[${Thread.currentThread().name}] - $bytesRead bytes from $clientId")

val message = String(buffer.array().slice(0 until bytesRead).toByteArray(), StandardCharsets.UTF_8)
println("[${Thread.currentThread().name}] - PAYLOAD { $message }")
}
}
}

0 comments on commit 18308cc

Please sign in to comment.