diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..89f9ac0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+out/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..5c98b42
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,2 @@
+# Default ignored files
+/workspace.xml
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..1bec35e
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..79ee123
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..16533ee
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/KotlinJavaRuntime.xml b/.idea/libraries/KotlinJavaRuntime.xml
new file mode 100644
index 0000000..1a7265d
--- /dev/null
+++ b/.idea/libraries/KotlinJavaRuntime.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/org_java_websocket_Java_WebSocket_1_4_0.xml b/.idea/libraries/org_java_websocket_Java_WebSocket_1_4_0.xml
new file mode 100644
index 0000000..5266850
--- /dev/null
+++ b/.idea/libraries/org_java_websocket_Java_WebSocket_1_4_0.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..e0844bc
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..71844b8
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chat-server.iml b/chat-server.iml
new file mode 100644
index 0000000..72d6a6b
--- /dev/null
+++ b/chat-server.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Main.kt b/src/Main.kt
new file mode 100644
index 0000000..bf36c3d
--- /dev/null
+++ b/src/Main.kt
@@ -0,0 +1,58 @@
+import org.java_websocket.WebSocket
+import org.java_websocket.handshake.ClientHandshake
+import org.java_websocket.server.WebSocketServer
+import java.net.InetSocketAddress
+
+class ChatServer(port: Int) : WebSocketServer(InetSocketAddress(port)) {
+
+ private var nextId = 0
+
+ override fun onOpen(connection: WebSocket, handshake: ClientHandshake?) {
+ val id = ++nextId
+
+ println("#$id connected")
+ connection.setAttachment(id)
+ }
+
+ override fun onClose(connection: WebSocket, code: Int, reason: String?, remote: Boolean) {
+ println("#${connection.getAttachment()} disconnected")
+ }
+
+ override fun onMessage(connection: WebSocket, message: String) {
+ val toClientMessage = "${connection.getAttachment()}: $message"
+
+ connections.filter(WebSocket::isOpen).forEach { openedConnection ->
+ try {
+ openedConnection.send(toClientMessage)
+ } catch (t: Throwable) {
+ }
+ }
+ }
+
+ override fun onStart() {
+ println("server starts on port $port")
+ }
+
+ override fun onError(connection: WebSocket, e: Exception?) {
+ println("error: $e")
+ }
+}
+
+object Main {
+
+ @JvmStatic
+ fun main(vararg args: String) {
+ val server = ChatServer(DEFAULT_PORT).apply {
+ start()
+ }
+
+ Runtime.getRuntime().addShutdownHook(object : Thread() {
+
+ override fun run() {
+ server.stop()
+ }
+ })
+ }
+
+ private const val DEFAULT_PORT = 8885
+}