Обработка пакета 16 с пуш токенами
This commit is contained in:
@@ -9,6 +9,7 @@ import com.rosetta.im.executors.Executor0Handshake;
|
||||
import com.rosetta.im.executors.Executor10RequestUpdate;
|
||||
import com.rosetta.im.executors.Executor11Typeing;
|
||||
import com.rosetta.im.executors.Executor15RequestTransport;
|
||||
import com.rosetta.im.executors.Executor16PushNotification;
|
||||
import com.rosetta.im.executors.Executor1UserInfo;
|
||||
import com.rosetta.im.executors.Executor24DeviceResolve;
|
||||
import com.rosetta.im.executors.Executor3Search;
|
||||
@@ -27,6 +28,7 @@ import com.rosetta.im.packet.Packet0Handshake;
|
||||
import com.rosetta.im.packet.Packet10RequestUpdate;
|
||||
import com.rosetta.im.packet.Packet11Typeing;
|
||||
import com.rosetta.im.packet.Packet15RequestTransport;
|
||||
import com.rosetta.im.packet.Packet16PushNotification;
|
||||
import com.rosetta.im.packet.Packet1UserInfo;
|
||||
import com.rosetta.im.packet.Packet23DeviceList;
|
||||
import com.rosetta.im.packet.Packet24DeviceResolve;
|
||||
@@ -62,6 +64,17 @@ public class Boot {
|
||||
private Configuration configuration;
|
||||
private ServerConfiguration serverConfiguration;
|
||||
|
||||
/**
|
||||
* Конструктор по умолчанию, использует порт 3000 для сервера
|
||||
*/
|
||||
public Boot() {
|
||||
this(3000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализатор приложения
|
||||
* @param port Порт, на котором будет работать сервер. Если не указан, то будет использован порт 3000
|
||||
*/
|
||||
public Boot(int port) {
|
||||
this.packetManager = new PacketManager();
|
||||
this.eventManager = new EventManager();
|
||||
@@ -149,7 +162,11 @@ public class Boot {
|
||||
this.packetManager.registerPacket(9, Packet9DeviceNew.class);
|
||||
this.packetManager.registerPacket(10, Packet10RequestUpdate.class);
|
||||
this.packetManager.registerPacket(11, Packet11Typeing.class);
|
||||
//RESERVED 12 PACKET AVATAR (unused)
|
||||
//RESERVED 13 PACKET KERNEL UPDATE (unused)
|
||||
//RESERVED 14 PACKET APP UPDATE (unused)
|
||||
this.packetManager.registerPacket(15, Packet15RequestTransport.class);
|
||||
this.packetManager.registerPacket(16, Packet16PushNotification.class);
|
||||
this.packetManager.registerPacket(23, Packet23DeviceList.class);
|
||||
this.packetManager.registerPacket(24, Packet24DeviceResolve.class);
|
||||
|
||||
@@ -165,6 +182,7 @@ public class Boot {
|
||||
this.packetManager.registerExecutor(10, new Executor10RequestUpdate(this.serverConfiguration));
|
||||
this.packetManager.registerExecutor(11, new Executor11Typeing(this.clientManager, this.packetManager));
|
||||
this.packetManager.registerExecutor(15, new Executor15RequestTransport(this.serverConfiguration));
|
||||
this.packetManager.registerExecutor(16, new Executor16PushNotification());
|
||||
this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Main {
|
||||
}
|
||||
|
||||
// Значение по умолчанию.
|
||||
return 8080;
|
||||
return 3000;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -236,6 +236,7 @@ public abstract class Repository<T> {
|
||||
* @param noResultType если true, то не указывать тип результата в запросе, используется для запросов типа UPDATE и DELETE
|
||||
* @return список сущностей
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public QuerySession<T> buildQuery(String queryString, HashMap<String, Object> parameters, boolean noResultType) {
|
||||
Session session = HibernateUtil.openSession();
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.rosetta.im.executors;
|
||||
|
||||
import com.rosetta.im.Failures;
|
||||
import com.rosetta.im.client.tags.ECIAuthentificate;
|
||||
import com.rosetta.im.database.entity.User;
|
||||
import com.rosetta.im.database.repository.UserRepository;
|
||||
import com.rosetta.im.packet.Packet16PushNotification;
|
||||
import com.rosetta.im.service.services.UserService;
|
||||
|
||||
import io.orprotocol.ProtocolException;
|
||||
import io.orprotocol.client.Client;
|
||||
import io.orprotocol.packet.PacketExecutor;
|
||||
|
||||
public class Executor16PushNotification extends PacketExecutor<Packet16PushNotification> {
|
||||
|
||||
private final UserRepository userRepository = new UserRepository();
|
||||
private final UserService userService = new UserService(userRepository);
|
||||
|
||||
@Override
|
||||
public void onPacketReceived(Packet16PushNotification packet, Client client) throws Exception, ProtocolException {
|
||||
ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class);
|
||||
if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()){
|
||||
/**
|
||||
* Клиент не авторизован, нельзя подписывать его на уведомления
|
||||
*/
|
||||
client.disconnect(Failures.HANDSHAKE_NOT_COMPLETED);
|
||||
return;
|
||||
}
|
||||
String notificationToken = packet.getNotificationToken();
|
||||
if(notificationToken.isEmpty()){
|
||||
/**
|
||||
* Клиент прислал пустой токен, отписывать его от уведомлений не нужно, а подписывать бессмысленно, просто игнорируем этот пакет
|
||||
*/
|
||||
return;
|
||||
}
|
||||
User user = userService.fromClient(client);
|
||||
switch (packet.getAction()) {
|
||||
case SUBSCRIBE:
|
||||
userService.subscribeToPushNotifications(user, notificationToken);
|
||||
break;
|
||||
case UNSUBSCRIBE:
|
||||
userService.unsubscribeFromPushNotifications(user, notificationToken);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.rosetta.im.packet;
|
||||
|
||||
import com.rosetta.im.packet.runtime.NetworkNotificationAction;
|
||||
|
||||
import io.orprotocol.Stream;
|
||||
import io.orprotocol.packet.Packet;
|
||||
|
||||
/**
|
||||
* Packet16PushNotification бросается клиентом для подписки на пуш уведомления
|
||||
*/
|
||||
public class Packet16PushNotification extends Packet {
|
||||
|
||||
private String notificationToken;
|
||||
private NetworkNotificationAction action;
|
||||
|
||||
@Override
|
||||
public void read(Stream stream) {
|
||||
this.notificationToken = stream.readString();
|
||||
this.action = NetworkNotificationAction.fromCode(stream.readInt8());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream write() {
|
||||
Stream stream = new Stream();
|
||||
stream.writeInt16(this.packetId);
|
||||
stream.writeString(notificationToken);
|
||||
stream.writeInt8(action.getCode());
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить токен пуш уведомлений, который нужно подписать или отписать в зависимости от action
|
||||
* @return токен пуш уведомлений
|
||||
*/
|
||||
public String getNotificationToken() {
|
||||
return notificationToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить действие, которое нужно выполнить с токеном пуш уведомлений. SUBSCRIBE - подписать этот токен на пуш уведомления, UNSUBSCRIBE - отписать этот токен от пуш уведомлений
|
||||
* @return действие, которое нужно выполнить с токеном пуш уведомлений
|
||||
*/
|
||||
public NetworkNotificationAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает токен пуш уведомлений, который нужно подписать или отписать в зависимости от action
|
||||
* @param notificationToken токен пуш уведомлений
|
||||
*/
|
||||
public void setNotificationToken(String notificationToken) {
|
||||
this.notificationToken = notificationToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает действие, которое нужно выполнить с токеном пуш уведомлений. SUBSCRIBE - подписать этот токен на пуш уведомления, UNSUBSCRIBE - отписать этот токен от пуш уведомлений
|
||||
* @param action действие, которое нужно выполнить с токеном пуш уведомлений
|
||||
*/
|
||||
public void setAction(NetworkNotificationAction action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.rosetta.im.packet.runtime;
|
||||
|
||||
/**
|
||||
* Используется в Packet16PushNotification для указания действия, которое нужно выполнить с токеном пуш уведомлений.
|
||||
*/
|
||||
public enum NetworkNotificationAction {
|
||||
/**
|
||||
* Подписать этот токен на пуш уведомления. Если токен уже был подписан, то ничего не произойдет.
|
||||
*/
|
||||
SUBSCRIBE(0),
|
||||
/**
|
||||
* Отписать этот токен от пуш уведомлений. Если токен не был подписан, то ничего не произойдет.
|
||||
*/
|
||||
UNSUBSCRIBE(1);
|
||||
|
||||
private final int code;
|
||||
|
||||
NetworkNotificationAction(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static NetworkNotificationAction fromCode(int code) {
|
||||
for (NetworkNotificationAction action : values()) {
|
||||
if (action.code == code) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown NetworkNotificationAction code: " + code);
|
||||
}
|
||||
}
|
||||
@@ -60,4 +60,34 @@ public class UserService extends Service<UserRepository> {
|
||||
return user != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Подписывает пользователя на пуш уведомления, добавляя токен в его список токенов. Если токен уже был добавлен, то ничего не произойдет.
|
||||
* @param user пользователь, которого нужно подписать на пуш уведомления
|
||||
* @param notificationToken токен пуш уведомлений, который нужно добавить пользователю. Если токен уже был добавлен, то ничего не произойдет
|
||||
*/
|
||||
public void subscribeToPushNotifications(User user, String notificationToken) {
|
||||
List<String> tokens = user.getNotificationsTokens();
|
||||
if(tokens.contains(notificationToken)){
|
||||
return;
|
||||
}
|
||||
tokens.add(notificationToken);
|
||||
user.setNotificationsTokens(tokens);
|
||||
this.getRepository().update(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Отписывает пользователя от пуш уведомлений, удаляя токен из его списка токенов. Если токена не было, то ничего не произойдет.
|
||||
* @param user пользователь, которого нужно отписать от пуш уведомлений
|
||||
* @param notificationToken токен пуш уведомлений, который нужно удалить у пользователя. Если токена не было, то ничего не произойдет
|
||||
*/
|
||||
public void unsubscribeFromPushNotifications(User user, String notificationToken) {
|
||||
List<String> tokens = user.getNotificationsTokens();
|
||||
if(!tokens.contains(notificationToken)){
|
||||
return;
|
||||
}
|
||||
tokens.remove(notificationToken);
|
||||
user.setNotificationsTokens(tokens);
|
||||
this.getRepository().update(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user