Обработка пакета печати
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.client.OnlineManager;
|
||||||
import com.rosetta.im.event.EventManager;
|
import com.rosetta.im.event.EventManager;
|
||||||
import com.rosetta.im.executors.Executor0Handshake;
|
import com.rosetta.im.executors.Executor0Handshake;
|
||||||
|
import com.rosetta.im.executors.Executor11Typeing;
|
||||||
import com.rosetta.im.executors.Executor1UserInfo;
|
import com.rosetta.im.executors.Executor1UserInfo;
|
||||||
import com.rosetta.im.executors.Executor24DeviceResolve;
|
import com.rosetta.im.executors.Executor24DeviceResolve;
|
||||||
import com.rosetta.im.executors.Executor3Search;
|
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.Color;
|
||||||
import com.rosetta.im.logger.enums.LogLevel;
|
import com.rosetta.im.logger.enums.LogLevel;
|
||||||
import com.rosetta.im.packet.Packet0Handshake;
|
import com.rosetta.im.packet.Packet0Handshake;
|
||||||
|
import com.rosetta.im.packet.Packet11Typeing;
|
||||||
import com.rosetta.im.packet.Packet1UserInfo;
|
import com.rosetta.im.packet.Packet1UserInfo;
|
||||||
import com.rosetta.im.packet.Packet23DeviceList;
|
import com.rosetta.im.packet.Packet23DeviceList;
|
||||||
import com.rosetta.im.packet.Packet24DeviceResolve;
|
import com.rosetta.im.packet.Packet24DeviceResolve;
|
||||||
@@ -129,6 +131,7 @@ public class Boot {
|
|||||||
this.packetManager.registerPacket(7, Packet7Read.class);
|
this.packetManager.registerPacket(7, Packet7Read.class);
|
||||||
this.packetManager.registerPacket(8, Packet8Delivery.class);
|
this.packetManager.registerPacket(8, Packet8Delivery.class);
|
||||||
this.packetManager.registerPacket(9, Packet9DeviceNew.class);
|
this.packetManager.registerPacket(9, Packet9DeviceNew.class);
|
||||||
|
this.packetManager.registerPacket(11, Packet11Typeing.class);
|
||||||
this.packetManager.registerPacket(23, Packet23DeviceList.class);
|
this.packetManager.registerPacket(23, Packet23DeviceList.class);
|
||||||
this.packetManager.registerPacket(24, Packet24DeviceResolve.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(4, new Executor4OnlineState(this.onlineManager, this.clientManager));
|
||||||
this.packetManager.registerExecutor(6, new Executor6Message(this.clientManager, this.packetManager));
|
this.packetManager.registerExecutor(6, new Executor6Message(this.clientManager, this.packetManager));
|
||||||
this.packetManager.registerExecutor(7, new Executor7Read(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));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Обновляем системную метку времени в соотвествии с сервером, так как у клиентов могут быть например неправильно настроены часы
|
* Обновляем системную метку времени в соотвествии с сервером,
|
||||||
|
* так как у клиентов могут быть например неправильно настроены часы
|
||||||
* или разные часовые пояса
|
* или разные часовые пояса
|
||||||
*/
|
*/
|
||||||
packet.setTimestamp(System.currentTimeMillis());
|
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 {
|
public class PacketBaseDialog extends Packet {
|
||||||
|
|
||||||
|
|||||||
@@ -75,15 +75,41 @@ public class MessageDispatcher {
|
|||||||
/**
|
/**
|
||||||
* Отправляет личное сообщение получателю
|
* Отправляет личное сообщение получателю
|
||||||
* @param packet пакет с личным сообщением
|
* @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 fromPublicKey = packet.getFromPublicKey();
|
||||||
String toPublicKey = packet.getToPublicKey();
|
String toPublicKey = packet.getToPublicKey();
|
||||||
this.clientManager.sendPacketToAuthorizedPK(toPublicKey, packet);
|
this.clientManager.sendPacketToAuthorizedPK(toPublicKey, packet);
|
||||||
|
|
||||||
|
if(!bufferizationNeed){
|
||||||
|
/**
|
||||||
|
* Указан флаг, что буферизация не нужна, сообщения с этим флагом не будут доставлены если
|
||||||
|
* оппонент оффлайн
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Сохраняем сообщение в буфер на случай если получатель офлайн, или нам нужна будет синхронизация сообщений для получателя
|
* Сохраняем сообщение в буфер на случай если получатель офлайн, или нам нужна будет синхронизация сообщений для получателя
|
||||||
*/
|
*/
|
||||||
this.bufferService.pushPacketToBuffer(fromPublicKey, toPublicKey, packet);
|
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