première version du chat
This commit is contained in:
commit
8c959ec818
|
@ -0,0 +1,2 @@
|
|||
.idea
|
||||
out
|
Binary file not shown.
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||
<orderEntry type="library" name="kWebSocket" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -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<Client>;
|
||||
val messages : Stack<Pair<Client,String>>;
|
||||
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<Any?>(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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Channel>;
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: MainKt
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import seekdasky.kWebSocket.Server
|
||||
|
||||
|
||||
fun main(args: Array<String>){
|
||||
val server = Server("0.0.0.0",9999,null);
|
||||
|
||||
server.addListener(ChannelDispatcher(server));
|
||||
server.startServer();
|
||||
|
||||
server.block();
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
class Stack<T>(list:MutableList<T>):Iterator<T> {
|
||||
|
||||
var itCounter: Int = 0
|
||||
|
||||
var items: MutableList<T> = 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")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue