Обработка пакета печати
This commit is contained in:
@@ -4,6 +4,7 @@ import com.rosetta.im.client.ClientManager;
|
||||
import com.rosetta.im.client.OnlineManager;
|
||||
import com.rosetta.im.event.EventManager;
|
||||
import com.rosetta.im.executors.Executor0Handshake;
|
||||
import com.rosetta.im.executors.Executor11Typeing;
|
||||
import com.rosetta.im.executors.Executor1UserInfo;
|
||||
import com.rosetta.im.executors.Executor24DeviceResolve;
|
||||
import com.rosetta.im.executors.Executor3Search;
|
||||
@@ -19,6 +20,7 @@ import com.rosetta.im.logger.Logger;
|
||||
import com.rosetta.im.logger.enums.Color;
|
||||
import com.rosetta.im.logger.enums.LogLevel;
|
||||
import com.rosetta.im.packet.Packet0Handshake;
|
||||
import com.rosetta.im.packet.Packet11Typeing;
|
||||
import com.rosetta.im.packet.Packet1UserInfo;
|
||||
import com.rosetta.im.packet.Packet23DeviceList;
|
||||
import com.rosetta.im.packet.Packet24DeviceResolve;
|
||||
@@ -129,6 +131,7 @@ public class Boot {
|
||||
this.packetManager.registerPacket(7, Packet7Read.class);
|
||||
this.packetManager.registerPacket(8, Packet8Delivery.class);
|
||||
this.packetManager.registerPacket(9, Packet9DeviceNew.class);
|
||||
this.packetManager.registerPacket(11, Packet11Typeing.class);
|
||||
this.packetManager.registerPacket(23, Packet23DeviceList.class);
|
||||
this.packetManager.registerPacket(24, Packet24DeviceResolve.class);
|
||||
|
||||
@@ -141,6 +144,7 @@ public class Boot {
|
||||
this.packetManager.registerExecutor(4, new Executor4OnlineState(this.onlineManager, this.clientManager));
|
||||
this.packetManager.registerExecutor(6, new Executor6Message(this.clientManager, this.packetManager));
|
||||
this.packetManager.registerExecutor(7, new Executor7Read(this.clientManager, this.packetManager));
|
||||
this.packetManager.registerExecutor(11, new Executor11Typeing(this.clientManager, this.packetManager));
|
||||
this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.rosetta.im.executors;
|
||||
|
||||
import com.rosetta.im.Failures;
|
||||
import com.rosetta.im.client.ClientManager;
|
||||
import com.rosetta.im.client.tags.ECIAuthentificate;
|
||||
import com.rosetta.im.packet.Packet11Typeing;
|
||||
import com.rosetta.im.service.dispatch.MessageDispatcher;
|
||||
|
||||
import io.orprotocol.ProtocolException;
|
||||
import io.orprotocol.client.Client;
|
||||
import io.orprotocol.packet.PacketExecutor;
|
||||
import io.orprotocol.packet.PacketManager;
|
||||
|
||||
public class Executor11Typeing extends PacketExecutor<Packet11Typeing> {
|
||||
|
||||
private final MessageDispatcher messageDispatcher;
|
||||
|
||||
public Executor11Typeing(ClientManager clientManager, PacketManager packetManager) {
|
||||
this.messageDispatcher = new MessageDispatcher(clientManager, packetManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceived(Packet11Typeing packet, Client client) throws Exception, ProtocolException {
|
||||
ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class);
|
||||
String fromPublicKey = packet.getFromPublicKey();
|
||||
String toPublicKey = packet.getToPublicKey();
|
||||
|
||||
if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()){
|
||||
/**
|
||||
* Если пользователь не авторизован он не может отправлять пакет печати
|
||||
*/
|
||||
client.disconnect(Failures.HANDSHAKE_NOT_COMPLETED);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!eciAuthentificate.getPublicKey().equals(fromPublicKey)){
|
||||
/**
|
||||
* Если клиент пытается отправить сообщение от отправителя,
|
||||
* которым он не является
|
||||
*/
|
||||
client.disconnect(Failures.DATA_MISSMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fromPublicKey.equals(toPublicKey)){
|
||||
/**
|
||||
* Отправка пакета печати самому себе, не кикаем пользователя, так как это ни на что не
|
||||
* влияет, просто ничего не делаем
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаляем приватный ключ чтобы не показать его оппоненту
|
||||
*/
|
||||
packet.setPrivateKey("");
|
||||
|
||||
if(toPublicKey.startsWith("#group:")){
|
||||
/**
|
||||
* Пакет печати отправляется в группу, отправляем всем участникам
|
||||
*/
|
||||
this.messageDispatcher.sendGroup(packet, client, eciAuthentificate);
|
||||
}else{
|
||||
/**
|
||||
* Пакет печати отправляется обычному оппоненту (пользователь),
|
||||
* отправляем его, при этом выключаем буфферизацию, потому что пакет печати действителен
|
||||
* только "здесь и сейчас", его не нужно видеть офлайн пользователям
|
||||
*/
|
||||
this.messageDispatcher.sendPeer(packet, client, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -95,7 +95,8 @@ public class Executor6Message extends PacketExecutor<Packet6Message> {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Обновляем системную метку времени в соотвествии с сервером, так как у клиентов могут быть например неправильно настроены часы
|
||||
* Обновляем системную метку времени в соотвествии с сервером,
|
||||
* так как у клиентов могут быть например неправильно настроены часы
|
||||
* или разные часовые пояса
|
||||
*/
|
||||
packet.setTimestamp(System.currentTimeMillis());
|
||||
|
||||
29
src/main/java/com/rosetta/im/packet/Packet11Typeing.java
Normal file
29
src/main/java/com/rosetta/im/packet/Packet11Typeing.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.rosetta.im.packet;
|
||||
|
||||
import com.rosetta.im.packet.base.PacketBaseDialog;
|
||||
|
||||
import io.orprotocol.Stream;
|
||||
|
||||
/**
|
||||
* Пакет отвечающий за индикацию печати в диалогах
|
||||
*/
|
||||
public class Packet11Typeing extends PacketBaseDialog {
|
||||
|
||||
@Override
|
||||
public void read(Stream stream) {
|
||||
this.privateKey = stream.readString();
|
||||
this.fromPublicKey = stream.readString();
|
||||
this.toPublicKey = stream.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream write() {
|
||||
Stream stream = new Stream();
|
||||
stream.writeInt16(this.packetId);
|
||||
stream.writeString(this.privateKey);
|
||||
stream.writeString(this.fromPublicKey);
|
||||
stream.writeString(this.toPublicKey);
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,14 @@ import io.orprotocol.packet.Packet;
|
||||
|
||||
/**
|
||||
* Базовый пакет для диалогов между пользователями
|
||||
*
|
||||
* ВОПРОС: Почему мы должны отправлять fromPublicKey с клиента, если сервер
|
||||
* может получить fromPublicKey из хэндшейка?
|
||||
* ОТВЕТ: Клиенты (оппоненты) должны понимать, от кого им приходит например пакет сообщения
|
||||
* или печати с сервера (from), чтобы производить с отправителем какие-либо действия (например показать
|
||||
* имя печатающего или отрендерить аватарку отправтеля сообщения), если бы поле fromPublicKey заполнял
|
||||
* сервер - это бы выглядело не логично. Это не влияет на безопасность, так как каждый Exectuor
|
||||
* верифицирует поле fromPublicKey сравнивая его с публичным ключом фактического отправителя.
|
||||
*/
|
||||
public class PacketBaseDialog extends Packet {
|
||||
|
||||
|
||||
@@ -75,15 +75,41 @@ public class MessageDispatcher {
|
||||
/**
|
||||
* Отправляет личное сообщение получателю
|
||||
* @param packet пакет с личным сообщением
|
||||
* @param client клиент отправляющий пакет
|
||||
* @param bufferizationNeed флаг указывающий на то, что сообщение нужно буфферизировать,
|
||||
* чтобы доставить пользователям если они не онлайн, если указать false то этот пакет получит
|
||||
* только пользователь который были в сети
|
||||
*/
|
||||
public void sendPeer(PacketBaseDialog packet, Client client) throws ProtocolException {
|
||||
public void sendPeer(PacketBaseDialog packet, Client client, boolean bufferizationNeed) throws ProtocolException {
|
||||
String fromPublicKey = packet.getFromPublicKey();
|
||||
String toPublicKey = packet.getToPublicKey();
|
||||
this.clientManager.sendPacketToAuthorizedPK(toPublicKey, packet);
|
||||
|
||||
if(!bufferizationNeed){
|
||||
/**
|
||||
* Указан флаг, что буферизация не нужна, сообщения с этим флагом не будут доставлены если
|
||||
* оппонент оффлайн
|
||||
*/
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Сохраняем сообщение в буфер на случай если получатель офлайн, или нам нужна будет синхронизация сообщений для получателя
|
||||
*/
|
||||
this.bufferService.pushPacketToBuffer(fromPublicKey, toPublicKey, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправляет личное сообщение получателю с буферизацией
|
||||
* @param packet пакет сообщения
|
||||
* @param client клиент отправляющий пакет
|
||||
* @throws ProtocolException
|
||||
*/
|
||||
public void sendPeer(PacketBaseDialog packet, Client client) throws ProtocolException {
|
||||
/**
|
||||
* По умолчанию буферизация включена, чтобы не терять сообщения
|
||||
*/
|
||||
this.sendPeer(packet, client, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user