commit 8c959ec81844b7bafdfe68ee5cd7b14e24e315d4 Author: SeekDaSky Date: Mon Dec 4 14:13:20 2017 +0100 première version du chat diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9fb18b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +out diff --git a/lib/org.json.jar b/lib/org.json.jar new file mode 100644 index 0000000..40a325d Binary files /dev/null and b/lib/org.json.jar differ diff --git a/ndli1718.iml b/ndli1718.iml new file mode 100644 index 0000000..db8bb7f --- /dev/null +++ b/ndli1718.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Channel.kt b/src/Channel.kt new file mode 100644 index 0000000..f856630 --- /dev/null +++ b/src/Channel.kt @@ -0,0 +1,95 @@ +import org.json.JSONArray +import org.json.JSONObject +import seekdasky.kWebSocket.Client +import seekdasky.kWebSocket.Event +import seekdasky.kWebSocket.Listeners.AsynchronousListener +import seekdasky.kWebSocket.Message.*; + +class Channel : AsynchronousListener { + + val channelName : String; + var clients : MutableList; + val messages : Stack>; + var lock = false; + + constructor(chanName : String){ + this.channelName = chanName; + this.clients = mutableListOf(); + this.messages = Stack(mutableListOf()); + } + + override fun filter(c: Client): Boolean { + return this.channelName == c.URL; + } + + override fun processClosed(e: Event) { + System.out.println("Client left the channel: "+this.channelName) + this.clients.remove(e.client); + } + + override fun processConnection(c: Client) { + this.clients.add(c); + c.data["IsLogged"] = false; + } + + override fun processEvent(e: Event) { + var json = JSONObject(e.message.getString()) + if(e.client.data["IsLogged"] != true){ + //json format : {username:xxx} + if(json.getString("name") != null){ + e.client.data["IsLogged"] = true; + e.client.data["Username"] = json.getString("name"); + + json = JSONObject(); + json.put("success",true); + json.put("error",""); + e.client.send(buildTextMessage(json.toString())); + + val array = JSONArray(); + synchronized(this.lock,{ + this.messages.forEach { + array.put(JSONArray(listOf(it.first.data["Username"],it.second))) + } + }) + + json = JSONObject(); + json.put("error",false); + json.put("msg",array); + e.client.send(buildTextMessage(json.toString())); + + }else{ + //tried to access chat without logging in + json = JSONObject(""); + json.put("success",false); + json.put("error","You must send your credential before sending anything else"); + e.client.send(buildTextMessage(json.toString())); + } + + return; + } + + if(json.has("message")){ + synchronized(this.lock,{ + this.lock = true; + this.messages.push(Pair(e.client,json.getString("message"))) + if(this.messages.count() > 20){ + this.messages.pop(); + } + }); + + val array = JSONArray(); + array.put(JSONArray(listOf(e.client.data["Username"],json.getString("message")))) + + json = JSONObject(); + json.put("error",false); + json.put("msg",array); + for(c in this.clients){ + if(c != e.client && c.data["IsLogged"] == true){ + c.send(buildTextMessage(json.toString())); + } + } + }else{ + System.out.println("unknown JSON: "+json.toString()); + } + } +} \ No newline at end of file diff --git a/src/ChannelDispatcher.kt b/src/ChannelDispatcher.kt new file mode 100644 index 0000000..d48d915 --- /dev/null +++ b/src/ChannelDispatcher.kt @@ -0,0 +1,43 @@ +import seekdasky.kWebSocket.Client +import seekdasky.kWebSocket.Event +import seekdasky.kWebSocket.Listeners.AsynchronousListener +import seekdasky.kWebSocket.Server + +class ChannelDispatcher : AsynchronousListener{ + + val serv : Server; + private var channels : MutableList; + + constructor(serv : Server){ + this.serv = serv; + this.channels = mutableListOf(); + } + + override fun filter(c: Client): Boolean { + for(chan in this.channels){ + if(chan.channelName == c.URL){ + return false; + } + } + + return true; + } + + override fun processClosed(e: Event) { + //no client should arrive here + } + + override fun processConnection(c: Client) { + System.out.println("new channel created: "+c.URL); + //if a client is handled here it means we have no channel at this address, let's create it + var newChan = Channel(c.URL); + this.serv.addListener(newChan); + //we transfer the client to the new channel + newChan.processConnection(c); + this.channels.add(newChan); + } + + override fun processEvent(e: Event) { + //no client should arrive here + } +} \ No newline at end of file diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..da202ef --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: MainKt + diff --git a/src/Main.kt b/src/Main.kt new file mode 100644 index 0000000..c3546d0 --- /dev/null +++ b/src/Main.kt @@ -0,0 +1,11 @@ +import seekdasky.kWebSocket.Server + + +fun main(args: Array){ + val server = Server("0.0.0.0",9999,null); + + server.addListener(ChannelDispatcher(server)); + server.startServer(); + + server.block(); +} \ No newline at end of file diff --git a/src/Stack.kt b/src/Stack.kt new file mode 100644 index 0000000..e30d60b --- /dev/null +++ b/src/Stack.kt @@ -0,0 +1,55 @@ +class Stack(list:MutableList):Iterator { + + var itCounter: Int = 0 + + var items: MutableList = list + + + fun isEmpty():Boolean = this.items.isEmpty() + + fun count():Int = this.items.count() + + fun push(element:T) { + val position = this.count() + this.items.add(position, element) + } + + override fun toString() = this.items.toString() + + fun pop():T? { + if (this.isEmpty()) { + return null + } else { + val item = this.items.count() - 1 + return this.items.removeAt(item) + } + } + + fun peek():T? { + if (isEmpty()) { + return null + } else { + return this.items[this.items.count() - 1] + } + } + + override fun hasNext(): Boolean { + val hasNext = itCounter < count() + + // As soon as condition fails, reset the counter + if (!hasNext) itCounter = 0 + + return hasNext + } + + override fun next(): T { + if (hasNext()) { + val topPos: Int = (count() - 1) - itCounter + itCounter++ + return this.items[topPos] + } else { + throw NoSuchElementException("No such element") + } + } + +} \ No newline at end of file