Skip to content

Commit

Permalink
Merge pull request #47 from stzups/temp
Browse files Browse the repository at this point in the history
v0.3.2 Rework protocol, document serialization
  • Loading branch information
griffinht authored Apr 2, 2021
2 parents 1c46199 + 05a2194 commit bee9cc8
Show file tree
Hide file tree
Showing 61 changed files with 1,148 additions and 654 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,11 @@ SQL data persistence
- Add environment variable config method
- Fix send rate of client
- Remove flatfile, add runtime (in memory only) and PostgresSQL database
- Move frontend to independent HTTP server (nginx)
- Move frontend to independent HTTP server (nginx)

### v0.3.2
Rework protocol, document serialization

- Canvas objects instead of points
- Rename packets to messages
- Add better serialization/deserialization methods
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.stzups.board.data.database.postgres;

import io.netty.buffer.Unpooled;
import net.stzups.board.data.database.Database;
import net.stzups.board.data.objects.Document;
import net.stzups.board.data.objects.User;
Expand Down Expand Up @@ -99,7 +100,7 @@ public Document getDocument(long id) {
System.out.println("no owner for document");
return null;
}
document = new Document(id, user, resultSet.getString("name"));//todo binary data
document = new Document(id, user, resultSet.getString("name"), Unpooled.buffer(0));//todo binary data
documents.put(document.getId(), document);
}
return document;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package net.stzups.board.data.objects;

import io.netty.buffer.ByteBuf;
import net.stzups.board.BoardRoom;
import net.stzups.board.data.objects.canvas.Point;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.stzups.board.data.objects.canvas.Canvas;

public class Document {
private static final String DEFAULT_DOCUMENT_NAME = "Untitled Document";
Expand All @@ -16,19 +11,27 @@ public class Document {
private User owner;
private String name;
private String inviteCode;
private Map<User, List<Point>> points = new HashMap<>();
private Canvas canvas;

/**
* New document
*/
public Document(User owner) {
this.id = BoardRoom.getSecureRandom().nextLong();
this.owner = owner;
owner.getOwnedDocuments().add(id);
this.name = DEFAULT_DOCUMENT_NAME;
this.canvas = new Canvas();
}

public Document(long id, User owner, String name) {
/**
* Serialize document from db
*/
public Document(long id, User owner, String name, ByteBuf byteBuf) {
this.id = id;
this.owner = owner;
this.name = name;
this.canvas = new Canvas(byteBuf);
}

public long getId() {
Expand All @@ -43,17 +46,8 @@ public User getOwner() {
return owner;
}

public Map<User, List<Point>> getPoints() {
return points;
}

public void addPoints(User user, Point[] points) {
List<Point> pts = this.points.get(user);
if (pts == null) {
pts = new ArrayList<>();
}
pts.addAll(Arrays.asList(points));
this.points.put(user, pts);
public Canvas getCanvas() {
return canvas;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class UserSession {
private long hash;

public UserSession(User user, long hash) {//todo hash
this.token = BoardRoom.getSecureRandom().nextLong();
this.token = BoardRoom.getSecureRandom().nextLong();//https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence
this.userId = user.getId();
this.creationTime = System.currentTimeMillis();//todo security issue? round/fuzz by a few seconds?
this.hash = hash;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package net.stzups.board.data.objects.canvas;

import io.netty.buffer.ByteBuf;
import net.stzups.board.data.objects.canvas.object.CanvasObject;
import net.stzups.board.data.objects.canvas.object.CanvasObjectType;
import net.stzups.board.data.objects.canvas.object.CanvasObjectWrapper;

import java.util.HashMap;
import java.util.Map;

public class Canvas {
private Map<CanvasObjectType, Map<Short, CanvasObject>> canvasObjects = new HashMap<>();

public Canvas() {

}

/**
* Deserializes canvas from db
*/
public Canvas(ByteBuf byteBuf) {
for (int i = 0; i < byteBuf.readUnsignedByte(); i++) {
CanvasObjectType canvasObjectType = CanvasObjectType.valueOf(byteBuf.readUnsignedByte());
Map<Short, CanvasObject> map = new HashMap<>();
canvasObjects.put(canvasObjectType, map);
for (int j = 0; j < byteBuf.readUnsignedShort(); j++) {
map.put(byteBuf.readShort(), CanvasObject.getCanvasObject(canvasObjectType, byteBuf));
}
}
}

public void update(Map<CanvasObjectType, Map<Short, CanvasObjectWrapper>> updateCanvasObjects) {
for (Map.Entry<CanvasObjectType, Map<Short, CanvasObjectWrapper>> entry : updateCanvasObjects.entrySet()) {
Map<Short, CanvasObject> map = canvasObjects.get(entry.getKey());
if (map == null) {
map = new HashMap<>();
}
for (Map.Entry<Short, CanvasObjectWrapper> entry1 : entry.getValue().entrySet()) {
map.put(entry1.getKey(), entry1.getValue().getCanvasObject());
}
}
}

public void delete(Canvas canvas) {
delete(canvas.canvasObjects);
}

public void delete(Map<CanvasObjectType, Map<Short, CanvasObject>> deleteCanvasObjects) {
for (Map.Entry<CanvasObjectType, Map<Short, CanvasObject>> entry : deleteCanvasObjects.entrySet()) {
Map<Short, CanvasObject> map = canvasObjects.get(entry.getKey());
if (map == null) {
System.out.println("cant delete " + entry.getKey() + ", its already gone");
} else {
for (Map.Entry<Short, CanvasObject> entry1 : entry.getValue().entrySet()) {
map.remove(entry1.getKey());
}
}
}
}

public void clear() {
canvasObjects.clear();
}

public void serialize(ByteBuf byteBuf) {
byteBuf.writeByte((byte) canvasObjects.size());
for (Map.Entry<CanvasObjectType, Map<Short, CanvasObject>> entry : canvasObjects.entrySet()) {
byteBuf.writeByte((byte) entry.getKey().getId());
byteBuf.writeShort((short) entry.getValue().size());
for (Map.Entry<Short, CanvasObject> entry1 : entry.getValue().entrySet()) {
byteBuf.writeShort(entry1.getKey());
entry1.getValue().serialize(byteBuf);
}
}
}

public boolean isEmpty() {
return canvasObjects.isEmpty();
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.stzups.board.data.objects.canvas.object;

import io.netty.buffer.ByteBuf;
import net.stzups.board.data.objects.canvas.object.objects.Shape;

public class CanvasObject {
private short x;
private short y;

public CanvasObject(ByteBuf byteBuf) {
x = byteBuf.readShort();
y = byteBuf.readShort();
}

public void serialize(ByteBuf byteBuf) {
byteBuf.writeShort(x);
byteBuf.writeShort(y);
}

public static CanvasObject getCanvasObject(CanvasObjectType canvasObjectType, ByteBuf byteBuf) {
CanvasObject canvasObject;
switch (canvasObjectType) {
case SHAPE:
canvasObject = new Shape(byteBuf);
break;
default:
canvasObject = null;
}
return canvasObject;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package net.stzups.board.data.objects.canvas;
package net.stzups.board.data.objects.canvas.object;

import io.netty.util.collection.IntObjectHashMap;

import java.util.EnumSet;
import java.util.Map;

public enum CanvasObjectType {
POINT(0),
SHAPE(0),
;

private static Map<Integer, CanvasObjectType> objectTypeMap = new IntObjectHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package net.stzups.board.data.objects.canvas.object;

import io.netty.buffer.ByteBuf;

public class CanvasObjectWrapper {
private byte dt;
private CanvasObject canvasObject;

public CanvasObjectWrapper(CanvasObjectType canvasObjectType, ByteBuf byteBuf) {
dt = byteBuf.readByte();
canvasObject = CanvasObject.getCanvasObject(canvasObjectType, byteBuf);
}

public CanvasObject getCanvasObject() {
return canvasObject;
}

public void serialize(ByteBuf byteBuf) {
byteBuf.writeByte(dt);
canvasObject.serialize(byteBuf);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.stzups.board.data.objects.canvas.object.objects;

import io.netty.buffer.ByteBuf;
import net.stzups.board.data.objects.canvas.object.CanvasObject;

public class Shape extends CanvasObject {
private int width;
private int height;

public Shape(ByteBuf byteBuf) {
super(byteBuf);
width = byteBuf.readUnsignedShort();
height = byteBuf.readUnsignedShort();
}

public void serialize(ByteBuf byteBuf) {
super.serialize(byteBuf);
byteBuf.writeShort((short) width);
byteBuf.writeShort((short) height);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.netty.channel.Channel;
import net.stzups.board.BoardRoom;
import net.stzups.board.data.objects.User;
import net.stzups.board.data.objects.canvas.Canvas;
import net.stzups.board.server.websocket.protocol.server.ServerMessage;

import java.util.ArrayList;
Expand Down Expand Up @@ -47,10 +48,10 @@ void sendMessage(ServerMessage serverMessage) {
channel.writeAndFlush(Collections.singletonList(serverMessage));
}

void sendMessages() {
void flushMessages() {
if (messages.size() > 0) {
channel.writeAndFlush(messages);
messages = new ArrayList<>();
messages = new ArrayList<>();//clear() won't work here as the above line does not block and writes later
}
}

Expand All @@ -66,4 +67,9 @@ void disconnect() {
public String toString() {
return "Client{user=" + user + ",address=" + channel.remoteAddress() + "}";
}

@Override
public int hashCode() {
return id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
import net.stzups.board.data.objects.UserSession;
import net.stzups.board.server.websocket.protocol.client.ClientMessage;
import net.stzups.board.server.websocket.protocol.client.messages.ClientMessageCreateDocument;
import net.stzups.board.server.websocket.protocol.client.messages.ClientMessageDraw;
import net.stzups.board.server.websocket.protocol.client.messages.ClientMessageHandshake;
import net.stzups.board.server.websocket.protocol.client.messages.ClientMessageOpenDocument;
import net.stzups.board.server.websocket.protocol.client.messages.ClientMessageUpdateCanvas;
import net.stzups.board.server.websocket.protocol.server.messages.ServerMessageAddDocument;
import net.stzups.board.server.websocket.protocol.server.messages.ServerMessageAddUser;
import net.stzups.board.server.websocket.protocol.server.messages.ServerMessageDrawClient;
import net.stzups.board.server.websocket.protocol.server.messages.ServerMessageHandshake;

import java.util.HashMap;
Expand All @@ -40,10 +39,8 @@ public void handlerAdded(ChannelHandlerContext ctx) {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ClientMessage message) {
switch (message.getMessageType()) {
case DRAW: {
ClientMessageDraw clientMessageDraw = (ClientMessageDraw) message;
room.getDocument().addPoints(client.getUser(), clientMessageDraw.getPoints());
room.queueMessageExcept(new ServerMessageDrawClient(client, clientMessageDraw.getPoints()), client);//todo this has tons of latency
case UPDATE_CANVAS: {
room.updateClient(client, ((ClientMessageUpdateCanvas) message).getCanvasObjects());
break;
}
case OPEN_DOCUMENT: {
Expand Down Expand Up @@ -106,7 +103,7 @@ protected void channelRead0(ChannelHandlerContext ctx, ClientMessage message) {
client.queueMessage(new ServerMessageAddDocument(BoardRoom.getDatabase().getDocument(id)));
}
}
client.sendMessages();
client.flushMessages();

break;
}
Expand Down
Loading

0 comments on commit bee9cc8

Please sign in to comment.