Added chat history stuff.
This commit is contained in:
parent
468758c7ab
commit
4faba0d2eb
|
@ -82,4 +82,13 @@ public interface Message {
|
|||
if (read != length) throw new IOException("Not all bytes of a string of length " + length + " could be read.");
|
||||
return new String(data, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
default void writeEnum(Enum<?> value, DataOutputStream o) throws IOException {
|
||||
o.writeInt(value.ordinal());
|
||||
}
|
||||
|
||||
default <T extends Enum<?>> T readEnum(Class<T> e, DataInputStream i) throws IOException {
|
||||
int ordinal = i.readInt();
|
||||
return e.getEnumConstants()[ordinal];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package nl.andrewl.concord_core.msg.types;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import nl.andrewl.concord_core.msg.Message;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A message which clients can send to the server to request some messages from
|
||||
* the server's history of all sent messages from a particular source. Every
|
||||
* request must provide the id of the source that messages should be fetched
|
||||
* from, in addition to the type of source (channel, thread, dm).
|
||||
* <p>
|
||||
* The query string is a specially-formatted string that allows you to
|
||||
* filter results to only certain messages, using different parameters that
|
||||
* are separated by the <code>;</code> character.
|
||||
* </p>
|
||||
* <p>
|
||||
* All query parameters are of the form <code>param=value</code>, where
|
||||
* <code>param</code> is the case-sensitive name of the parameter, and
|
||||
* <code>value</code> is the value of the parameter.
|
||||
* </p>
|
||||
* <p>
|
||||
* The following query parameters are supported:
|
||||
* <ul>
|
||||
* <li><code>count</code> - Fetch up to N messages. Minimum of 1, and
|
||||
* a server-specific maximum count, usually no higher than 1000.</li>
|
||||
* <li><code>from</code> - ISO-8601 timestamp indicating the timestamp
|
||||
* after which messages should be fetched. Only messages after this
|
||||
* point in time are returned.</li>
|
||||
* <li><code>to</code> - ISO-8601 timestamp indicating the timestamp
|
||||
* before which messages should be fetched. Only messages before this
|
||||
* point in time are returned.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>
|
||||
* Responses to this request are sent via {@link ChatHistoryResponse}, where
|
||||
* the list of messages is always sorted by the timestamp.
|
||||
* </p>
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class ChatHistoryRequest implements Message {
|
||||
public enum Source {CHANNEL, THREAD, DIRECT_MESSAGE}
|
||||
|
||||
private long sourceId;
|
||||
private Source sourceType;
|
||||
private String query;
|
||||
|
||||
@Override
|
||||
public int getByteCount() {
|
||||
return Long.BYTES + Integer.BYTES + getByteSize(this.query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream o) throws IOException {
|
||||
o.writeLong(sourceId);
|
||||
writeEnum(this.sourceType, o);
|
||||
writeString(this.query, o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInputStream i) throws IOException {
|
||||
this.sourceId = i.readLong();
|
||||
this.sourceType = readEnum(Source.class, i);
|
||||
this.query = readString(i);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package nl.andrewl.concord_core.msg.types;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import nl.andrewl.concord_core.msg.Message;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The response that a server sends to a {@link ChatHistoryRequest}.
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class ChatHistoryResponse implements Message {
|
||||
private long sourceId;
|
||||
private ChatHistoryRequest.Source sourceType;
|
||||
List<Chat> messages;
|
||||
|
||||
@Override
|
||||
public int getByteCount() {
|
||||
int count = Long.BYTES + Integer.BYTES + Integer.BYTES;
|
||||
for (var message : this.messages) {
|
||||
count += message.getByteCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream o) throws IOException {
|
||||
o.writeLong(this.sourceId);
|
||||
writeEnum(this.sourceType, o);
|
||||
o.writeInt(messages.size());
|
||||
for (var message : this.messages) {
|
||||
message.write(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInputStream i) throws IOException {
|
||||
this.sourceId = i.readInt();
|
||||
this.sourceType = readEnum(ChatHistoryRequest.Source.class, i);
|
||||
int messageCount = i.readInt();
|
||||
Chat[] messages = new Chat[messageCount];
|
||||
for (int k = 0; k < messageCount; k++) {
|
||||
Chat c = new Chat();
|
||||
c.read(i);
|
||||
messages[k] = c;
|
||||
}
|
||||
this.messages = List.of(messages);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import lombok.extern.java.Log;
|
|||
import nl.andrewl.concord_core.msg.Message;
|
||||
import nl.andrewl.concord_core.msg.Serializer;
|
||||
import nl.andrewl.concord_core.msg.types.Chat;
|
||||
import nl.andrewl.concord_core.msg.types.ChatHistoryRequest;
|
||||
import nl.andrewl.concord_core.msg.types.Identification;
|
||||
import nl.andrewl.concord_core.msg.types.ServerWelcome;
|
||||
|
||||
|
@ -65,6 +66,8 @@ public class ClientThread extends Thread {
|
|||
var msg = Serializer.readMessage(this.in);
|
||||
if (msg instanceof Chat chat) {
|
||||
this.server.handleChat(chat);
|
||||
} else if (msg instanceof ChatHistoryRequest historyRequest) {
|
||||
this.server.handleHistoryRequest(historyRequest, this);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.info("Client disconnected: " + e.getMessage());
|
||||
|
|
|
@ -3,6 +3,9 @@ package nl.andrewl.concord_server;
|
|||
import lombok.extern.java.Log;
|
||||
import nl.andrewl.concord_core.msg.Serializer;
|
||||
import nl.andrewl.concord_core.msg.types.Chat;
|
||||
import nl.andrewl.concord_core.msg.types.ChatHistoryRequest;
|
||||
import org.dizitart.no2.Document;
|
||||
import org.dizitart.no2.Nitrite;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
@ -19,10 +22,14 @@ public class ConcordServer implements Runnable {
|
|||
private final Map<Long, ClientThread> clients = new ConcurrentHashMap<>(32);
|
||||
private final int port;
|
||||
private final Random random;
|
||||
private final Nitrite db;
|
||||
|
||||
public ConcordServer(int port) {
|
||||
this.port = port;
|
||||
this.random = new SecureRandom();
|
||||
this.db = Nitrite.builder()
|
||||
.filePath("concord-server.db")
|
||||
.openOrCreate();
|
||||
}
|
||||
|
||||
public long registerClient(ClientThread clientThread) {
|
||||
|
@ -37,6 +44,15 @@ public class ConcordServer implements Runnable {
|
|||
}
|
||||
|
||||
public void handleChat(Chat chat) {
|
||||
var collection = db.getCollection("channel-TEST");
|
||||
long messageId = this.random.nextLong();
|
||||
Document doc = Document.createDocument(Long.toHexString(messageId), "message")
|
||||
.put("senderId", Long.toHexString(chat.getSenderId()))
|
||||
.put("senderNickname", chat.getSenderNickname())
|
||||
.put("timestamp", chat.getTimestamp())
|
||||
.put("message", chat.getMessage());
|
||||
collection.insert(doc);
|
||||
db.commit();
|
||||
System.out.println(chat.getSenderNickname() + ": " + chat.getMessage());
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(chat.getByteCount());
|
||||
try {
|
||||
|
@ -51,6 +67,10 @@ public class ConcordServer implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
public void handleHistoryRequest(ChatHistoryRequest request, ClientThread clientThread) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ServerSocket serverSocket;
|
||||
|
|
Loading…
Reference in New Issue