org.springframework.messaging.simp.SimpMessagingTemplate

Here are the examples of the java api org.springframework.messaging.simp.SimpMessagingTemplate taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

192 Examples 7

19 View Source File : NotificationService.java
License : Apache License 2.0
Project Creator : zeebe-io

@Controller
public clreplaced NotificationService {

    @Autowired
    private SimpMessagingTemplate webSocket;

    public void sendNewTask() {
        final TaskNotification notification = new TaskNotification("new tasks");
        webSocket.convertAndSend("/notifications/tasks", notification);
    }

    public void sendTaskCanceled() {
        final TaskNotification notification = new TaskNotification("tasks canceled");
        webSocket.convertAndSend("/notifications/tasks", notification);
    }
}

19 View Source File : LauncherController.java
License : Apache License 2.0
Project Creator : zebrunner

@CrossOrigin
@RequestMapping(path = "api/launchers", produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
@RequiredArgsConstructor
public clreplaced LauncherController extends AbstractController implements LauncherDoreplacedentedController {

    private final LauncherService launcherService;

    private final Mapper mapper;

    private final SimpMessagingTemplate websocketTemplate;

    @PreAuthorize("hasPermission('MODIFY_LAUNCHERS')")
    @PostMapping()
    @Override
    public LauncherDTO createLauncher(@RequestBody @Valid LauncherDTO launcherDTO, @RequestParam(name = "automationServerId") Long automationServerId) {
        Launcher launcher = mapper.map(launcherDTO, Launcher.clreplaced);
        Long principalId = Long.valueOf(getPrincipalId());
        launcher = launcherService.createLauncher(launcher, principalId, automationServerId);
        return mapper.map(launcher, LauncherDTO.clreplaced);
    }

    @PreAuthorize("hasAnyPermission('MODIFY_LAUNCHERS', 'VIEW_LAUNCHERS')")
    @GetMapping("/{id}")
    @Override
    public LauncherDTO getLauncherById(@PathVariable("id") Long id) {
        Launcher launcher = launcherService.getLauncherById(id);
        return mapper.map(launcher, LauncherDTO.clreplaced);
    }

    @PreAuthorize("hasAnyPermission('MODIFY_LAUNCHERS', 'VIEW_LAUNCHERS')")
    @GetMapping()
    @Override
    public List<LauncherDTO> getAllLaunchers() {
        List<Launcher> launchers = launcherService.getAllLaunchers(Long.valueOf(getPrincipalId()));
        return launchers.stream().map(launcher -> mapper.map(launcher, LauncherDTO.clreplaced)).collect(Collectors.toList());
    }

    @PreAuthorize("hasPermission('MODIFY_LAUNCHERS')")
    @PutMapping()
    @Override
    public LauncherDTO updateLauncher(@RequestBody @Valid LauncherDTO launcherDTO) {
        Launcher launcher = mapper.map(launcherDTO, Launcher.clreplaced);
        launcher = launcherService.updateLauncher(launcher);
        return mapper.map(launcher, LauncherDTO.clreplaced);
    }

    @PreAuthorize("hasPermission('MODIFY_LAUNCHERS')")
    @DeleteMapping("/{id}")
    @Override
    public void deleteLauncherById(@PathVariable("id") Long id) {
        launcherService.deleteLauncherById(id);
    }

    @PreAuthorize("hasAnyPermission('MODIFY_LAUNCHERS', 'VIEW_LAUNCHERS')")
    @PostMapping("/build")
    @Override
    public void build(@RequestBody @Valid LauncherDTO launcherDTO, @RequestParam(name = "providerId", required = false) Long providerId) throws IOException {
        Launcher launcher = mapper.map(launcherDTO, Launcher.clreplaced);
        String ciRunId = launcherService.buildLauncherJob(launcher, Long.valueOf(getPrincipalId()), providerId);
        websocketTemplate.convertAndSend(getLauncherRunsWebsocketPath(), new LauncherRunPush(launcher, ciRunId));
    }

    @GetMapping("/hooks/{ref}")
    @Override
    public String buildByWebHook(@PathVariable("ref") String ref, @RequestParam(value = "callbackUrl", required = false) String callbackUrl) throws IOException {
        return launcherService.buildLauncherJobByPresetRef(ref, callbackUrl, Long.valueOf(getPrincipalId()));
    }

    @PreAuthorize("hasAnyPermission('MODIFY_LAUNCHERS', 'VIEW_LAUNCHERS')")
    @GetMapping("/build/number")
    @Override
    public Integer getBuildNumber(@RequestParam("queueItemUrl") String queueItemUrl, @RequestParam(name = "automationServerId") Long automationServerId) {
        return launcherService.getBuildNumber(queueItemUrl, automationServerId);
    }

    @PreAuthorize("hasPermission('MODIFY_LAUNCHERS')")
    @PostMapping("/scanner")
    @Override
    public JobResult runScanner(@RequestBody @Valid LauncherScannerType launcherScannerType, @RequestParam(name = "automationServerId") Long automationServerId) {
        return launcherService.buildScannerJob(Long.valueOf(getPrincipalId()), launcherScannerType.getBranch(), launcherScannerType.getScmAccountId(), launcherScannerType.isRescan(), automationServerId);
    }

    @PreAuthorize("hasPermission('MODIFY_LAUNCHERS')")
    @DeleteMapping("/scanner/{buildNumber}")
    @Override
    public void cancelScanner(@PathVariable("buildNumber") int buildNumber, @RequestParam("scmAccountId") Long scmAccountId, @RequestParam("rescan") boolean rescan, @RequestParam(name = "automationServerId") Long automationServerId) {
        launcherService.abortScannerJob(scmAccountId, buildNumber, rescan, automationServerId);
    }

    @PreAuthorize("hasPermission('MODIFY_LAUNCHERS')")
    @GetMapping("/scanner/{buildNumber}/status")
    public boolean getScannerStatus(@PathVariable("buildNumber") int buildNumber, @RequestParam("scmAccountId") Long scmAccountId, @RequestParam("rescan") boolean rescan, @RequestParam(name = "automationServerId") Long automationServerId) {
        return launcherService.isScannerJobInProgress(scmAccountId, buildNumber, rescan, automationServerId);
    }

    @PreAuthorize("hasPermission('MODIFY_LAUNCHERS')")
    @PostMapping("/create")
    @Override
    public List<LauncherDTO> scanLaunchersFromJenkins(@RequestBody @Valid JenkinsJobsScanResultDTO jenkinsJobsScanResultDTO) {
        Long principalId = Long.valueOf(getPrincipalId());
        List<JenkinsJob> jenkinsJobs = jenkinsJobsScanResultDTO.getJenkinsJobs().stream().map(jenkinsLauncher -> mapper.map(jenkinsLauncher, JenkinsJob.clreplaced)).collect(Collectors.toList());
        List<Launcher> launchers = launcherService.mergeLaunchersWithJenkinsJobs(jenkinsJobs, jenkinsJobsScanResultDTO.getRepo(), jenkinsJobsScanResultDTO.isSuccess(), principalId);
        List<LauncherDTO> launcherDTOS = launchers.stream().map(launcher -> mapper.map(launcher, LauncherDTO.clreplaced)).collect(Collectors.toList());
        websocketTemplate.convertAndSend(getLaunchersWebsocketPath(), new LauncherPush(launcherDTOS, jenkinsJobsScanResultDTO.getUserId(), jenkinsJobsScanResultDTO.isSuccess()));
        return launcherDTOS;
    }

    @PreAuthorize("hasAnyPermission('MODIFY_LAUNCHERS', 'VIEW_LAUNCHERS')")
    @PatchMapping("/{id}")
    @Override
    public UserLauncherPreference patchUserLauncherPreference(@RequestBody @Valid PatchDescriptor descriptor, @PathVariable("id") Long id) {
        return PatchDecorator.<UserLauncherPreference, PatchOperation>instance().descriptor(descriptor).operation(PatchOperation.clreplaced).<Boolean>when(PatchOperation.SAVE_FAVORITE).withParameter(Boolean::valueOf).then(favorite -> launcherService.markLauncherAsFavorite(id, Long.valueOf(getPrincipalId()), favorite)).after().decorate();
    }

    enum PatchOperation {

        SAVE_FAVORITE
    }
}

19 View Source File : OrderCompleteUpdaterRestApi.java
License : MIT License
Project Creator : youhusky

@RestController
@RequestMapping("/api")
@Slf4j
public clreplaced OrderCompleteUpdaterRestApi {

    @Autowired
    private SimpMessagingTemplate template;

    @RequestMapping(value = "/orders", method = RequestMethod.POST)
    public void orderComplete(@RequestBody Order order) {
        log.info("Receive order = " + order.toString());
        if (order.getUserInfo().getId() == null) {
            order.getUserInfo().setId("");
        }
        if (order.getPaymentId() == null) {
            order.setPaymentId("");
        }
        if (order.getSpecialNote() == null) {
            order.setSpecialNote("");
        }
        template.convertAndSend("/topic/orders", order);
    }

    @RequestMapping(value = "/errors", method = RequestMethod.POST)
    public void orderComplete(@RequestBody String errorMessage) {
        log.info("Receive error = " + errorMessage);
        template.convertAndSend("/topic/orders", errorMessage);
    }
}

19 View Source File : WsController.java
License : MIT License
Project Creator : yidao620c

/**
 * WsController
 *
 * @author XiongNeng
 * @version 1.0
 * @since 2018/2/28
 */
@Controller
public clreplaced WsController {

    private final SimpMessagingTemplate messagingTemplate;

    @Autowired
    public WsController(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    @MessageMapping("/welcome")
    @SendTo("/topic/say")
    public ResponseMessage say(RequestMessage message) {
        System.out.println(message.getName());
        return new ResponseMessage("welcome," + message.getName() + " !");
    }

    /**
     * 定时推送消息
     */
    @Scheduled(fixedRate = 1000)
    public void callback() {
        // 发现消息
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        messagingTemplate.convertAndSend("/topic/callback", "定时推送消息时间: " + df.format(new Date()));
    }
}

19 View Source File : ExchangePushJob.java
License : Apache License 2.0
Project Creator : xunibidev

@Slf4j
@Component
public clreplaced ExchangePushJob {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private NettyHandler nettyHandler;

    private Map<String, List<ExchangeTrade>> tradesQueue = new HashMap<>();

    private Map<String, List<TradePlate>> plateQueue = new HashMap<>();

    private Map<String, List<CoinThumb>> thumbQueue = new HashMap<>();

    private Random rand = new Random();

    // 最后一次推送的盘口,仅仅是为了虚拟推送二设立的
    private Map<String, TradePlate> plateLastBuy = new HashMap<>();

    // 最后一次推送的盘口,仅仅是为了虚拟推送二设立的
    private Map<String, TradePlate> plateLastSell = new HashMap<>();

    public void addTrades(String symbol, List<ExchangeTrade> trades) {
        List<ExchangeTrade> list = tradesQueue.get(symbol);
        if (list == null) {
            list = new ArrayList<>();
            tradesQueue.put(symbol, list);
        }
        synchronized (list) {
            list.addAll(trades);
        }
    }

    public void addPlates(String symbol, TradePlate plate) {
        List<TradePlate> list = plateQueue.get(symbol);
        if (list == null) {
            list = new ArrayList<>();
            plateQueue.put(symbol, list);
        }
        synchronized (list) {
            list.add(plate);
        }
        if (plate.getDirection() == ExchangeOrderDirection.BUY) {
            // 更新最新盘口
            synchronized (plateLastBuy) {
                plateLastBuy.put(symbol, plate);
            }
        }
        if (plate.getDirection() == ExchangeOrderDirection.SELL) {
            // 更新最新盘口
            synchronized (plateLastSell) {
                plateLastSell.put(symbol, plate);
            }
        }
    }

    public void addThumb(String symbol, CoinThumb thumb) {
        List<CoinThumb> list = thumbQueue.get(symbol);
        if (list == null) {
            list = new ArrayList<>();
            thumbQueue.put(symbol, list);
        }
        synchronized (list) {
            list.add(thumb);
        }
    }

    @Scheduled(fixedRate = 300)
    public void pushTrade() {
        Iterator<Map.Entry<String, List<ExchangeTrade>>> entryIterator = tradesQueue.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, List<ExchangeTrade>> entry = entryIterator.next();
            String symbol = entry.getKey();
            List<ExchangeTrade> trades = entry.getValue();
            if (trades.size() > 0) {
                synchronized (trades) {
                    messagingTemplate.convertAndSend("/topic/market/trade/" + symbol, trades);
                    trades.clear();
                }
            }
        }
    }

    @Scheduled(fixedDelay = 500)
    public void pushPlate() {
        Iterator<Map.Entry<String, List<TradePlate>>> entryIterator = plateQueue.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, List<TradePlate>> entry = entryIterator.next();
            String symbol = entry.getKey();
            List<TradePlate> plates = entry.getValue();
            if (plates.size() > 0) {
                boolean hasPushAskPlate = false;
                boolean hasPushBidPlate = false;
                synchronized (plates) {
                    for (TradePlate plate : plates) {
                        if (plate.getDirection() == ExchangeOrderDirection.BUY && !hasPushBidPlate) {
                            hasPushBidPlate = true;
                        } else if (plate.getDirection() == ExchangeOrderDirection.SELL && !hasPushAskPlate) {
                            hasPushAskPlate = true;
                        } else {
                            continue;
                        }
                        // websocket推送盘口信息
                        messagingTemplate.convertAndSend("/topic/market/trade-plate/" + symbol, plate.toJSON(24));
                        // websocket推送深度信息
                        messagingTemplate.convertAndSend("/topic/market/trade-depth/" + symbol, plate.toJSON(50));
                        // netty推送
                        nettyHandler.handlePlate(symbol, plate);
                    }
                    plates.clear();
                }
            } else {
                // 不管盘口有没有变化,都推送一下数据,显得盘口交易很活跃的样子(这里获取到的盘口有可能是买盘,也可能是卖盘)
                TradePlate plateBuy = plateLastBuy.get(symbol);
                TradePlate plateSell = plateLastSell.get(symbol);
                if (plateBuy != null) {
                    // 随机修改盘口数据,然后推送
                    List<TradePlateItem> list = plateBuy.gereplacedems();
                    if (list.size() > 9) {
                        // 只要大于随机数的种子就行,这里的4是随意设置的
                        int randInt = rand.nextInt(9);
                        // 随机挑选一个,让盘口订单数量+50%
                        list.get(randInt).setAmount(list.get(randInt).getAmount().multiply(BigDecimal.valueOf(0.5)));
                        if (randInt > 0 && randInt < list.size() - 1) {
                            // 如果在中间,就可以变动价格
                            // 价格取前后价格居中的价格
                            list.get(randInt).setPrice(list.get(randInt - 1).getPrice().add(list.get(randInt + 1).getPrice()).divide(BigDecimal.valueOf(2), 8, RoundingMode.HALF_DOWN));
                        }
                        // websocket推送盘口信息
                        messagingTemplate.convertAndSend("/topic/market/trade-plate/" + symbol, plateBuy.toJSON(24));
                        // websocket推送深度信息
                        messagingTemplate.convertAndSend("/topic/market/trade-depth/" + symbol, plateBuy.toJSON(50));
                        // netty推送
                        nettyHandler.handlePlate(symbol, plateBuy);
                    }
                }
                if (plateSell != null) {
                    // 随机修改盘口数据,然后推送
                    List<TradePlateItem> list = plateSell.gereplacedems();
                    if (list.size() > 9) {
                        // 只要大于随机数的种子就行,这里的4是随意设置的
                        int randInt = rand.nextInt(9);
                        // 随机挑选一个,让盘口订单数量+50%
                        list.get(randInt).setAmount(list.get(randInt).getAmount().multiply(BigDecimal.valueOf(0.5)));
                        if (randInt > 0 && randInt < list.size() - 1) {
                            // 如果在中间,就可以变动价格
                            // 价格取前后价格居中的价格
                            list.get(randInt).setPrice(list.get(randInt - 1).getPrice().add(list.get(randInt + 1).getPrice()).divide(BigDecimal.valueOf(2), 8, RoundingMode.HALF_DOWN));
                        }
                        // websocket推送盘口信息
                        messagingTemplate.convertAndSend("/topic/market/trade-plate/" + symbol, plateSell.toJSON(24));
                        // websocket推送深度信息
                        messagingTemplate.convertAndSend("/topic/market/trade-depth/" + symbol, plateSell.toJSON(50));
                        // netty推送
                        nettyHandler.handlePlate(symbol, plateSell);
                    }
                }
            }
        }
    }

    @Scheduled(fixedRate = 300)
    public void pushThumb() {
        Iterator<Map.Entry<String, List<CoinThumb>>> entryIterator = thumbQueue.entrySet().iterator();
        log.info("thumbQueue::::" + JSON.toJSONString(thumbQueue));
        while (entryIterator.hasNext()) {
            Map.Entry<String, List<CoinThumb>> entry = entryIterator.next();
            String symbol = entry.getKey();
            List<CoinThumb> thumbs = entry.getValue();
            if (thumbs.size() > 0) {
                synchronized (thumbs) {
                    messagingTemplate.convertAndSend("/topic/market/thumb", thumbs.get(thumbs.size() - 1));
                    thumbs.clear();
                }
            }
        }
    }
}

19 View Source File : WebsocketMarketHandler.java
License : Apache License 2.0
Project Creator : xunibidev

@Slf4j
@Component
public clreplaced WebsocketMarketHandler implements MarketHandler {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private ExchangePushJob pushJob;

    /**
     * 推送币种简化信息
     * @param symbol
     * @param exchangeTrade
     * @param thumb
     */
    @Override
    public void handleTrade(String symbol, ExchangeTrade exchangeTrade, CoinThumb thumb) {
        // 推送缩略行情
        pushJob.addThumb(symbol, thumb);
    }

    @Override
    public void handleKLine(String symbol, KLine kLine) {
        // 推送K线数据
        messagingTemplate.convertAndSend("/topic/market/kline/" + symbol, kLine);
    }
}

19 View Source File : NettyHandler.java
License : Apache License 2.0
Project Creator : xunibidev

/**
 * 处理Netty订阅与取消订阅
 */
@HawkBean
public clreplaced NettyHandler {

    @Autowired
    private HawkPushServiceApi hawkPushService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private MessageHandler chatMessageHandler;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    /*
    @Autowired
    private ApnsHandler apnsHandler;
	*/
    public void subscribeTopic(Channel channel, String topic) {
        String userKey = channel.id().asLongText();
        NettyCacheUtils.keyChannelCache.put(channel, userKey);
        NettyCacheUtils.storeChannel(topic, channel);
        if (NettyCacheUtils.userKey.containsKey(userKey)) {
            NettyCacheUtils.userKey.get(userKey).add(topic);
        } else {
            Set<String> userkeys = new HashSet<>();
            userkeys.add(topic);
            NettyCacheUtils.userKey.put(userKey, userkeys);
        }
    }

    public void unsubscribeTopic(Channel channel, String topic) {
        String userKey = channel.id().asLongText();
        if (NettyCacheUtils.userKey.containsKey(userKey)) {
            NettyCacheUtils.userKey.get(userKey).remove(topic);
        }
        NettyCacheUtils.keyChannelCache.remove(channel);
    }

    /*@HawkMethod(cmd = NettyCommand.SUBSCRIBE_CHAT,version = NettyCommand.COMMANDS_VERSION)
    public QuoteMessage.SimpleResponse subscribeChat(byte[] body, ChannelHandlerContext ctx){
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("订阅:"+json.toJSONString());
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        String orderId = json.getString("orderId");
        String uid = json.getString("uid");
        if(StringUtils.isEmpty(uid) || StringUtils.isEmpty(orderId)){
            response.setCode(500).setMessage("订阅失败,参数错误");
        }
        else {
            String key = orderId + "-" + uid;
            subscribeTopic(ctx.channel(),key);
            response.setCode(0).setMessage("订阅成功");
        }
        return response.build();
    }*/
    @HawkMethod(cmd = NettyCommand.SUBSCRIBE_GROUP_CHAT)
    public QuoteMessage.SimpleResponse subscribeGroupChat(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("订阅GroupChat:" + json.toJSONString());
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        String uid = json.getString("uid");
        if (StringUtils.isEmpty(uid)) {
            response.setCode(500).setMessage("订阅失败,参数错误");
        } else {
            String key = uid;
            subscribeTopic(ctx.channel(), key);
            response.setCode(0).setMessage("订阅成功");
        }
        return response.build();
    }

    /*@HawkMethod(cmd = NettyCommand.UNSUBSCRIBE_CHAT)
    public QuoteMessage.SimpleResponse unsubscribeChat(byte[] body, ChannelHandlerContext ctx){
        System.out.println(ctx.channel().id());
        JSONObject json = JSON.parseObject(new String(body));
        String orderId = json.getString("orderId");
        String uid = json.getString("uid");
        String key = orderId+"-"+uid;
        unsubscribeTopic(ctx.channel(),key);
        apnsHandler.removeToken(uid);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("取消订阅成功");
        return response.build();
    }*/
    @HawkMethod(cmd = NettyCommand.UNSUBSCRIBE_GROUP_CHAT)
    public QuoteMessage.SimpleResponse unsubscribeGroupChat(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        String uid = json.getString("uid");
        String key = uid;
        unsubscribeTopic(ctx.channel(), key);
        // apnsHandler.removeToken(uid);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("取消订阅成功");
        return response.build();
    }

    @HawkMethod(cmd = NettyCommand.SUBSCRIBE_APNS)
    public QuoteMessage.SimpleResponse subscribeApns(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("订阅APNS推送:" + json.toJSONString());
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        String token = json.getString("token");
        String uid = json.getString("uid");
        if (StringUtils.isEmpty(uid) || StringUtils.isEmpty(token)) {
            response.setCode(500).setMessage("订阅失败,参数错误");
        } else {
            // apnsHandler.setToken(uid,token);
            response.setCode(0).setMessage("订阅成功");
        }
        return response.build();
    }

    @HawkMethod(cmd = NettyCommand.UNSUBSCRIBE_APNS)
    public QuoteMessage.SimpleResponse unsubscribeApns(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("取消订阅APNS推送:" + json.toJSONString());
        String uid = json.getString("uid");
        // apnsHandler.removeToken(uid);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("取消订阅成功");
        return response.build();
    }

    @HawkMethod(cmd = NettyCommand.SEND_CHAT)
    public QuoteMessage.SimpleResponse sendMessage(byte[] body, ChannelHandlerContext ctx) {
        System.out.println("发送消息:" + new String(body));
        RealTimeChatMessage message = JSON.parseObject(new String(body), RealTimeChatMessage.clreplaced);
        handleMessage(message);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("发送成功");
        return response.build();
    }

    /**
     * 推送消息
     * @param key
     * @param result
     */
    public void push(String key, Object result, short command) {
        byte[] body = JSON.toJSONString(result).getBytes();
        Set<Channel> channels = NettyCacheUtils.getChannel(key);
        if (channels != null && channels.size() > 0) {
            System.out.println("下发消息:key=" + key + ",result=" + JSON.toJSONString(result) + ",channel size=" + channels.size());
            hawkPushService.pushMsg(channels, command, body);
        }
    }

    public void handleMessage(RealTimeChatMessage message) {
        if (message.getMessageType() == MessageTypeEnum.NOTICE) {
            Order order = orderService.findOneByOrderId(message.getOrderId());
            ConfirmResult result = new ConfirmResult(message.getContent(), order.getStatus().getOrdinal());
            result.setUidFrom(message.getUidFrom());
            result.setOrderId(message.getOrderId());
            result.setNameFrom(message.getNameFrom());
            // push(message.getOrderId() + "-" + message.getUidTo(),result,NettyCommand.PUSH_CHAT);
            push(message.getUidTo(), result, NettyCommand.PUSH_GROUP_CHAT);
            messagingTemplate.convertAndSendToUser(message.getUidTo(), "/order-notice/" + message.getOrderId(), result);
        } else if (message.getMessageType() == MessageTypeEnum.NORMAL_CHAT) {
            ChatMessageRecord chatMessageRecord = new ChatMessageRecord();
            BeanUtils.copyProperties(message, chatMessageRecord);
            chatMessageRecord.setSendTime(DateUtils.getCurrentDate().getTime());
            chatMessageRecord.setFromAvatar(message.getAvatar());
            // 聊天消息保存到mogondb
            chatMessageHandler.handleMessage(chatMessageRecord);
            chatMessageRecord.setSendTimeStr(DateUtils.getDateStr(chatMessageRecord.getSendTime()));
            // 发送给指定用户(客户端订阅路径:/user/+uid+/+key)
            push(message.getUidTo(), chatMessageRecord, NettyCommand.PUSH_GROUP_CHAT);
            // push(message.getOrderId() + "-" + message.getUidTo(),chatMessageRecord,NettyCommand.PUSH_CHAT);
            // apnsHandler.handleMessage(message.getUidTo(),chatMessageRecord);
            messagingTemplate.convertAndSendToUser(message.getUidTo(), "/" + message.getOrderId(), chatMessageRecord);
        }
    }
}

19 View Source File : WebSocketController.java
License : MIT License
Project Creator : xlui

@Controller
@Slf4j
public clreplaced WebSocketController {

    // You cannot integrate WebSocket with JWT for token validate.
    private static final String token = "this is a token generated by your code!";

    private final SimpMessagingTemplate simpMessagingTemplate;

    public WebSocketController(SimpMessagingTemplate simpMessagingTemplate) {
        this.simpMessagingTemplate = simpMessagingTemplate;
    }

    /**
     * <code>@MessageMapping</code> defines the endpoint for receiving messages, client will send websocket message
     * to endpoints defined in this annotation.
     * <code>@SendTo</code> defines the return value's target endpoint of this method, clients which subscribe to
     * this endpoint will receive the return value of this method.
     * This method will simply send messages received to all clients that subscribe to endpoint specified in
     * <code>@SendTo</code>, just like a broadcast
     *
     * <code>@MessageMapping</code> 定义接收消息的端点,客户端发送 WebSocket 消息到此端点。
     * <code>@SendTo</code> 定义方法返回值发送的端点,订阅该端点的客户端可以收到服务器端的回复。
     * 此端点默认将收到的消息发送到所有订阅了 <code>@SendTo</code> 端点的客户端,相当于广播。
     *
     * @param message            client message
     * @param authorizationToken customize header, for token validate
     * @return return client message to all clients that subscribe to <code>/b</code>
     */
    // 
    @MessageMapping("/broadcast")
    @SendTo("/b")
    public Response broadcast(Message message, @Header(value = "authorization") String authorizationToken) {
        val response = new Response("Token check failed!");
        if (authorizationToken.equals(token)) {
            log.info("Token check success!!!");
            response.setResponse("Welcome, " + message.getName() + "!");
        } else {
            log.info(response.getResponse());
        }
        return response;
    }

    /**
     * Add a placeholder in <code>@MessageMapping</code> to get the dynamic param in websocket url, for dynamic
     * resending. Message sent to this endpoint will be resent to any clients that subscribe endpoint {@code /g/<groupId>}.
     * Just like a group chat.
     * <p>
     * 通过在 <code>@MessageMapping</code> 中添加消息占位符来获取 url 内容,从而动态转发。
     * 消息会发送到所有订阅了 {@code /g/<groupId>} 的客户端,实现效果相当于群聊
     *
     * @param groupID group id
     * @param message client message
     */
    @MessageMapping("/group/{groupID}")
    public void group(@DestinationVariable int groupID, Message message) {
        log.info("Receive group message: [" + groupID + " -> " + message.getName() + "]");
        Response response = new Response("Welcome to group " + groupID + ", " + message.getName() + "!");
        simpMessagingTemplate.convertAndSend("/g/" + groupID, response);
    }

    /**
     * Send message to specify user depend on {@link ChatMessage#getUserID}, each user will subscribe himself/herself's endpoint
     * {@code /user/<userId>/msg}, just like point to point chat.
     * <p>
     * 依据 {@code ChatMessage} 中的内容发送消息给特定用户,每个用户都订阅自己接受消息的端点
     * {@code /user/<userId>/msg},实现效果类似点对点聊天
     *
     * @param chatMessage 聊天消息
     */
    @MessageMapping("/chat")
    public void chat(ChatMessage chatMessage) {
        log.info("Receive point-to-point chat message: [" + chatMessage.getFromUserID() + " -> " + chatMessage.getUserID() + ", " + chatMessage.getMessage() + "]");
        Response response = new Response("Receive message from user " + chatMessage.getFromUserID() + ": " + chatMessage.getMessage());
        simpMessagingTemplate.convertAndSendToUser(String.valueOf(chatMessage.getUserID()), "/msg", response);
    }
}

19 View Source File : ServerTask.java
License : MIT License
Project Creator : xkcoding

/**
 * <p>
 * 服务器定时推送任务
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2018-12-14 16:04
 */
@Slf4j
@Component
public clreplaced ServerTask {

    @Autowired
    private SimpMessagingTemplate wsTemplate;

    /**
     * 按照标准时间来算,每隔 2s 执行一次
     */
    @Scheduled(cron = "0/2 * * * * ?")
    public void websocket() throws Exception {
        log.info("【推送消息】开始执行:{}", DateUtil.formatDateTime(new Date()));
        // 查询服务器状态
        Server server = new Server();
        server.copyTo();
        ServerVO serverVO = ServerUtil.wrapServerVO(server);
        Dict dict = ServerUtil.wrapServerDict(serverVO);
        wsTemplate.convertAndSend(WebSocketConsts.PUSH_SERVER, JSONUtil.toJsonStr(dict));
        log.info("【推送消息】执行结束:{}", DateUtil.formatDateTime(new Date()));
    }
}

19 View Source File : ChatServiceTest.java
License : MIT License
Project Creator : woowacourse-teams

@ExtendWith(MockitoExtension.clreplaced)
clreplaced ChatServiceTest {

    @Mock
    ChatRoomRepository chatRoomRepository;

    @Mock
    ChatRepository chatRepository;

    @Mock
    SimpMessagingTemplate simpMessagingTemplate;

    @Mock
    ChatSessionInformations chatSessionInformations;

    private ChatService chatService;

    @BeforeEach
    void setUp() {
        this.chatService = new ChatService(chatRoomRepository, chatRepository, simpMessagingTemplate, chatSessionInformations);
    }

    @Test
    void sendMessage() {
        Long noticeId = 1L;
        List<Chat> chats = Arrays.asList(Chat.of("하늘하늘한 동글", replacedleColor.AMBER, "message1", ChatRoom.from(noticeId)), Chat.of("찬란한 코일", replacedleColor.BAROSSA, "message2", ChatRoom.from(noticeId)), Chat.of("어슴프레한 유안", replacedleColor.DARK_ORCHID, "message3", ChatRoom.from(noticeId)));
        Set<ChatName> chatNames = new HashSet<>(Arrays.asList(ChatName.of("하늘하늘한 동글", replacedleColor.AMBER), ChatName.of("찬란한 코일", replacedleColor.BAROSSA), ChatName.of("어슴프레한 유안", replacedleColor.DARK_ORCHID)));
        ChatRoom chatRoom = ChatRoom.builder().noticeId(noticeId).chats(chats).build();
        MessageSendRequest messageSendRequest = new MessageSendRequest(noticeId, "하늘하늘한 동글", "메세지", replacedleColor.AMBER.getColor());
        given(chatRoomRepository.findByNoticeId(anyLong())).willReturn(Optional.of(chatRoom));
        given(chatRepository.save(any(Chat.clreplaced))).willReturn(Chat.of("하늘하늘한 동글", replacedleColor.AMBER, "메세지", chatRoom));
        doNothing().when(simpMessagingTemplate).convertAndSend(any(String.clreplaced), any(StompMessageResponse.clreplaced));
        chatService.sendMessage(messageSendRequest);
        verify(chatRoomRepository).findByNoticeId(eq(noticeId));
        verify(chatRepository).save(any());
        verify(simpMessagingTemplate).convertAndSend(any(), any(StompMessageResponse.clreplaced));
    }

    @DisplayName("noticeId에 해당하는 Chatroom이 존재할 경우 Chatroom 생성 하지 않음")
    @Test
    void connectWhenChatRoomDoesNotExist() {
        Long noticeId = 1L;
        List<Chat> chats = Arrays.asList(Chat.of("하늘하늘한 동글", replacedleColor.AMBER, "message1", ChatRoom.from(noticeId)), Chat.of("찬란한 코일", replacedleColor.BAROSSA, "message2", ChatRoom.from(noticeId)), Chat.of("어슴프레한 유안", replacedleColor.DARK_ORCHID, "message3", ChatRoom.from(noticeId)));
        ChatRoom chatRoom = ChatRoom.builder().noticeId(noticeId).chats(chats).build();
        given(chatRoomRepository.findByNoticeId(anyLong())).willReturn(Optional.of(chatRoom));
        given(chatSessionInformations.countSessionOn(anyLong())).willReturn(4);
        ChatRoomResponse chatRoomResponse = chatService.fetchChatRoomInfo(noticeId);
        verify(chatRoomRepository).findByNoticeId(eq(noticeId));
        verify(chatRoomRepository, never()).save(any());
        replacedertThat(chatRoomResponse).isNotNull();
        replacedertThat(chatRoomResponse.getMessageResponses()).isNotNull();
        List<MessageResponse> messageResponses = chatRoomResponse.getMessageResponses().getMessageResponses();
        replacedertAll(() -> replacedertEquals(messageResponses.get(0).getName(), "하늘하늘한 동글"), () -> replacedertEquals(messageResponses.get(1).getName(), "찬란한 코일"), () -> replacedertEquals(messageResponses.get(2).getName(), "어슴프레한 유안"), () -> replacedertThat(chatRoomResponse.getHeadCount()).isEqualTo(4));
    }

    @DisplayName("noticeId에 해당하는 Chatroom이 존재할 경우 Chatroom 생성")
    @Test
    void connectWhenChatRoomExist() {
        Long noticeId = 1L;
        List<Chat> chats = Arrays.asList(Chat.of("하늘하늘한 동글", replacedleColor.AMBER, "message1", ChatRoom.from(noticeId)), Chat.of("찬란한 코일", replacedleColor.BAROSSA, "message2", ChatRoom.from(noticeId)), Chat.of("어슴프레한 유안", replacedleColor.DARK_ORCHID, "message3", ChatRoom.from(noticeId)));
        ChatRoom chatRoom = ChatRoom.builder().noticeId(noticeId).chats(chats).build();
        given(chatRoomRepository.findByNoticeId(anyLong())).willReturn(Optional.of(chatRoom));
        given(chatSessionInformations.countSessionOn(anyLong())).willReturn(4);
        ChatRoomResponse chatRoomResponse = chatService.fetchChatRoomInfo(noticeId);
        verify(chatRoomRepository).findByNoticeId(eq(noticeId));
        replacedertThat(chatRoomResponse).isNotNull();
        replacedertThat(chatRoomResponse.getMessageResponses()).isNotNull();
        List<MessageResponse> messageResponses = chatRoomResponse.getMessageResponses().getMessageResponses();
        replacedertAll(() -> replacedertEquals(messageResponses.get(0).getName(), "하늘하늘한 동글"), () -> replacedertEquals(messageResponses.get(1).getName(), "찬란한 코일"), () -> replacedertEquals(messageResponses.get(2).getName(), "어슴프레한 유안"), () -> replacedertThat(chatRoomResponse.getHeadCount()).isEqualTo(4));
    }
}

19 View Source File : ChatService.java
License : MIT License
Project Creator : woowacourse-teams

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public clreplaced ChatService {

    public static final String PUBLISH_URL = "/channel/";

    private final ChatRoomRepository chatRoomRepository;

    private final ChatRepository chatRepository;

    private final SimpMessagingTemplate simpMessagingTemplate;

    private final ChatSessionInformations chatSessionInformations;

    @Transactional
    public void sendMessage(MessageSendRequest messageSendRequest) {
        ChatRoom chatRoom = getChatRoom(messageSendRequest.getNoticeId());
        Chat savedChat = saveChat(messageSendRequest, chatRoom);
        MessageResponse messageResponse = MessageResponse.from(savedChat);
        simpMessagingTemplate.convertAndSend(PUBLISH_URL + messageSendRequest.getNoticeId(), StompMessageResponse.of(StompMethodType.TALK, messageResponse));
    }

    private ChatRoom getChatRoom(Long noticeId) {
        return chatRoomRepository.findByNoticeId(noticeId).orElseThrow(() -> new NotExistException(String.format("noticeId = %s 를 가진 채팅방이 존재하지 않습니다.", noticeId)));
    }

    private Chat saveChat(MessageSendRequest messageSendRequest, ChatRoom chatRoom) {
        Chat chat = Chat.of(messageSendRequest.getName(), replacedleColor.from(messageSendRequest.getreplacedleColor()), messageSendRequest.getMessage(), chatRoom);
        return chatRepository.save(chat);
    }

    @Transactional
    public ChatRoomResponse fetchChatRoomInfo(Long noticeId) {
        ChatRoom chatRoom = getOrCreateChatRoom(noticeId);
        return ChatRoomResponse.of(chatRoom.getChats(), chatSessionInformations.countSessionOn(noticeId));
    }

    private ChatRoom getOrCreateChatRoom(Long noticeId) {
        return chatRoomRepository.findByNoticeId(noticeId).orElseGet(() -> chatRoomRepository.save(ChatRoom.from(noticeId)));
    }

    public void addNewSessionInfo(String sessionId, long noticeId) {
        ChatSessionInformation chatSessionInformation = chatSessionInformations.addSessionInfo(sessionId, noticeId);
        sendConnectionInformation(StompMethodType.ENTER, chatSessionInformation, sessionId);
    }

    public void disconnectSession(String sessionId) {
        ChatSessionInformation chatSessionInformation = chatSessionInformations.removeSession(sessionId);
        sendConnectionInformation(StompMethodType.QUIT, chatSessionInformation, sessionId);
    }

    private void sendConnectionInformation(StompMethodType stompMethodType, ChatSessionInformation info, String sessionId) {
        long noticeId = info.getNoticeId();
        ChatName chatName = info.getChatName();
        simpMessagingTemplate.convertAndSend(PUBLISH_URL + noticeId, StompMessageResponse.of(stompMethodType, ChatNameResponse.of(chatName, sessionId)));
    }
}

19 View Source File : KafkaTransactionsConsumerService.java
License : GNU General Public License v3.0
Project Creator : wlhbdp

@Service
@Slf4j
public clreplaced KafkaTransactionsConsumerService implements ConsumerSeekAware {

    private final SimpMessagingTemplate simpTemplate;

    private final ObjectMapper mapper = new ObjectMapper();

    @Value("${web-socket.topic.transactions}")
    private String transactionsWebSocketTopic;

    @Autowired
    public KafkaTransactionsConsumerService(SimpMessagingTemplate simpTemplate) {
        this.simpTemplate = simpTemplate;
    }

    @KafkaListener(id = "${kafka.listeners.transactions.id}", topics = "${kafka.topic.transactions}", groupId = "transactions")
    public void consumeTransactions(@Payload String message) {
        log.debug("{}", message);
        simpTemplate.convertAndSend(transactionsWebSocketTopic, message);
    }

    @Override
    public void registerSeekCallback(ConsumerSeekCallback callback) {
    }

    @Override
    public void onParreplacedionsreplacedigned(Map<TopicParreplacedion, Long> replacedignments, ConsumerSeekCallback callback) {
        replacedignments.forEach((t, o) -> callback.seekToEnd(t.topic(), t.parreplacedion()));
    }

    @Override
    public void onIdleContainer(Map<TopicParreplacedion, Long> replacedignments, ConsumerSeekCallback callback) {
    }
}

19 View Source File : WelComeJob.java
License : MIT License
Project Creator : wayn111

public void welCome() {
    SimpMessagingTemplate simpMessagingTemplate = SpringContextUtil.getBean(SimpMessagingTemplate.clreplaced);
    String sysName = configService.getValueByKey("sys.name");
    simpMessagingTemplate.convertAndSend("/topic/getResponse", "WelCome to " + sysName + "!");
    logger.info("执行自定义定时任务");
}

19 View Source File : WsController.java
License : MIT License
Project Creator : wayn111

/**
 * stomp消息路由
 */
@Controller
public clreplaced WsController {

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/message")
    public void message(Response message) {
        System.out.println(message);
        simpMessagingTemplate.convertAndSend("/topic/getResponse", Response.success("tip"));
    }
}

19 View Source File : NotifyRecordController.java
License : MIT License
Project Creator : wayn111

@RequestMapping("/oa/notifyRecord")
@Controller
public clreplaced NotifyRecordController extends BaseController {

    private static final String PREFIX = "oa/notifyRecord";

    @Autowired
    private NotifyRecordService notifyRecordService;

    @Autowired
    private UserService userService;

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @RequiresPermissions("oa:notifyRecord:list")
    @GetMapping
    public String NotifyRecordIndex(ModelMap modelMap) {
        modelMap.addAttribute("users", userService.selectUser2JsonObj());
        return PREFIX + "/notifyRecord";
    }

    @Log(value = "我的通知")
    @RequiresPermissions("oa:notifyRecord:list")
    @ResponseBody
    @PostMapping("/list")
    public Page<NotifyRecordVO> list(Model model, NotifyRecordVO notifyRecordVO) {
        notifyRecordVO.setReceiveUserId(getCurUserId());
        Page<NotifyRecordVO> page = getPage();
        // 设置通用查询字段
        ParameterUtil.set(notifyRecordVO);
        return notifyRecordService.selectNotifyRecordList(page, notifyRecordVO);
    }

    @RequiresPermissions("oa:notifyRecord:add")
    @GetMapping("/add")
    public String add(ModelMap modelMap) {
        return PREFIX + "/add";
    }

    @RequiresPermissions("oa:notifyRecord:list")
    @GetMapping("/{option}/{id}")
    public String option(ModelMap modelMap, @PathVariable("option") String option, @PathVariable("id") Long id) {
        NotifyRecordVO notifyRecordVO = notifyRecordService.selectNotifyByNotifyRecordId(id);
        // 将状态变为已读
        if (!notifyRecordVO.getRead()) {
            notifyRecordService.update().set("isRead", 1).eq("id", id).update();
        }
        simpMessagingTemplate.convertAndSendToUser(getCurUserId(), "/queue/notifyRecordTip", "");
        modelMap.put("notifyRecordVO", notifyRecordVO);
        return PREFIX + "/" + option;
    }

    @RequiresPermissions("oa:notifyRecord:add")
    @ResponseBody
    @PostMapping("/addSave")
    public Response addSave(ModelMap modelMap, NotifyRecord notifyRecord) {
        return Response.result(notifyRecordService.save(notifyRecord), "新增成功");
    }

    @RequiresPermissions("oa:notifyRecord:edit")
    @ResponseBody
    @PostMapping("/editSave")
    public Response editSave(ModelMap modelMap, NotifyRecord notifyRecord) {
        return Response.result(notifyRecordService.update(notifyRecord), "修改成功");
    }

    @Log(value = "我的通知", operator = Operator.DELETE)
    @RequiresPermissions("oa:notifyRecord:remove")
    @ResponseBody
    @DeleteMapping("/remove/{id}")
    public Response remove(ModelMap modelMap, @PathVariable("id") Long id) {
        return Response.result(notifyRecordService.remove(id), "删除成功");
    }

    @Log(value = "我的通知", operator = Operator.DELETE)
    @RequiresPermissions("oa:notifyRecord:remove")
    @ResponseBody
    @PostMapping("/batchRemove")
    public Response batchRemove(ModelMap modelMap, @RequestParam("ids[]") Long[] ids) {
        return Response.result(notifyRecordService.batchRemove(ids), "删除成功");
    }

    @PostMapping("/export")
    public void export(NotifyRecordVO notifyRecordVO, HttpServletResponse response) throws IOException {
        notifyRecordVO.setReceiveUserId(getCurUserId());
        // 设置通用查询字段
        ParameterUtil.set(notifyRecordVO);
        notifyRecordService.export(notifyRecordVO, response, request);
    }

    /**
     * 获取右上角通知图标最新状态
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/notifyRecordTip")
    public Page<NotifyRecordTip> notifyRecordTip() {
        Page<NotifyRecordTip> page = getPage(1, 5);
        return notifyRecordService.selectNotifyRecordTipList(page, getCurUserId());
    }
}

19 View Source File : MyRealm.java
License : MIT License
Project Creator : wayn111

public clreplaced MyRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private LogininforService logininforService;

    @Autowired
    private ConfigService configService;

    @Autowired
    private SessionDAO sessionDAO;

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    /**
     * 密码加密 测试
     *
     * @param args 测试
     */
    public static void main(String[] args) {
        // MD5,"原密码","盐",加密次数
        String pwd = new SimpleHash("MD5", "123456", "admin", 1024).toString();
        System.out.println(pwd);
        System.out.println(Boolean.valueOf("true"));
    }

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User sysUser = (User) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> roles = userRoleService.findRolesByUid(sysUser.getId());
        Set<String> permissions = roleMenuService.findMenusByUid(sysUser.getId());
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePreplacedwordToken token2 = (UsernamePreplacedwordToken) token;
        String username = token2.getUsername();
        // String preplacedword = ShiroUtil.md5encrypt(new String(token2.getPreplacedword()), username);
        User sysUser = userService.getOne(new QueryWrapper<User>().eq("userName", username));
        if (sysUser == null) {
            logininforService.addLog(username, Constants.LOGIN_FAIL, "用户不存在");
            throw new UnknownAccountException("用户不存在");
        }
        if (sysUser.getUserState() == -1) {
            logininforService.addLog(username, Constants.LOGIN_FAIL, "用户已被禁用");
            throw new UnknownAccountException("用户已被禁用");
        }
        // 此处不再需要做密码验证,由CredentialsMatch的实现做密码校验
        /*if (!sysUser.getPreplacedword().equals(preplacedword)) {
            throw new IncorrectCredentialsException("账号或密码不正确");
        }*/
        if (sysUser.getUserState().equals(StateEnum.DISABLE.getState())) {
            logininforService.addLog(username, Constants.LOGIN_FAIL, "该用户已被锁定,请稍后再试");
            throw new LockedAccountException("该用户已被锁定,请稍后再试");
        }
        // 是否进行单一用户登陆处理
        boolean singeUserAuth = Boolean.parseBoolean(configService.getValueByKey("sys.user.singeUserAuth"));
        if (singeUserAuth) {
            Collection<Session> activeSessions = sessionDAO.getActiveSessions();
            for (Session activeSession : activeSessions) {
                if (activeSession.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) != null) {
                    SimplePrincipalCollection principalCollection = (SimplePrincipalCollection) activeSession.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                    Object primaryPrincipal = principalCollection.getPrimaryPrincipal();
                    User user = (User) primaryPrincipal;
                    if (user.getUserName().equals(username)) {
                        // 单一用户登出逻辑,是否强制登出前一用户
                        boolean singeKickoutBefore = Boolean.parseBoolean(configService.getValueByKey("sys.user.singeKickoutBefore"));
                        if (!singeKickoutBefore) {
                            logininforService.addLog(username, Constants.LOGIN_FAIL, "该用户已登陆,请先登出!");
                            throw new AuthenticationException("该用户已登陆,请先登出!");
                        }
                        Session session = sessionDAO.readSession(activeSession.getId());
                        if (session != null) {
                            session.stop();
                            sessionDAO.delete(session);
                            simpMessagingTemplate.convertAndSendToUser(user.getId(), "/queue/getResponse", "新消息:" + "该账号已在其他机器登陆!");
                        }
                    }
                }
            }
        }
        // 盐值加密
        ByteSource byteSource = ByteSource.Util.bytes(username);
        return new SimpleAuthenticationInfo(sysUser, sysUser.getPreplacedword(), byteSource, getName());
    }

    public void clearCachedAuthorizationInfo() {
        doClearCache(SecurityUtils.getSubject().getPrincipals());
        clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }
}

19 View Source File : HelloController.java
License : Apache License 2.0
Project Creator : wangzihaogithub

/**
 * 我的房间Controller (供websocket客户端订阅或请求)
 *
 * @author wangzihao
 */
@RestController
public clreplaced HelloController {

    private Logger logger = LoggerFactory.getLogger(getClreplaced());

    // 所有在线的用户
    @Autowired
    private SimpUserRegistry userRegistry;

    // 发送消息的工具类 (可以主动回复客户端)
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    /**
     * 订阅房间
     *
     * @param message   消息
     * @param principal 订阅人的用户身份(当前登录人的信息)
     * @param username  被订阅人的账号
     * @param roomName  被订阅的房间名
     */
    @SubscribeMapping("/user/room/{username}/{roomName}")
    public void subscribeMyRoom(Message message, Principal principal, @DestinationVariable("username") String username, @DestinationVariable("roomName") String roomName) {
        logger.info("[" + principal.getName() + "]订阅了[" + username + "]的 [" + roomName + "] 房间");
    }

    /**
     * 接收消息
     *
     * @param message   客户端的数据
     * @param principal 当前登录人的信息
     */
    @MessageMapping("/receiveMessage")
    public void receiveMessage(Message message, Principal principal) {
        String payload = new String((byte[]) message.getPayload());
        logger.info("已收到[" + principal.getName() + "]的消息[" + payload + "] 当前在线人数[" + userRegistry.getUserCount() + "]");
    }
}

19 View Source File : UserRegistryMessageHandler.java
License : MIT License
Project Creator : Vip-Augus

/**
 * {@code MessageHandler} that handles user registry broadcasts from other
 * application servers and periodically broadcasts the content of the local
 * user registry.
 *
 * <p>The aggregated information is maintained in a {@link MultiServerUserRegistry}.
 *
 * @author Rossen Stoyanchev
 * @since 4.2
 */
public clreplaced UserRegistryMessageHandler implements MessageHandler, ApplicationListener<BrokerAvailabilityEvent> {

    private final MultiServerUserRegistry userRegistry;

    private final SimpMessagingTemplate brokerTemplate;

    private final String broadcastDestination;

    private final TaskScheduler scheduler;

    private final UserRegistryTask schedulerTask = new UserRegistryTask();

    @Nullable
    private volatile ScheduledFuture<?> scheduledFuture;

    private long registryExpirationPeriod = TimeUnit.SECONDS.toMillis(20);

    /**
     * Constructor.
     * @param userRegistry the registry with local and remote user registry information
     * @param brokerTemplate template for broadcasting local registry information
     * @param broadcastDestination the destination to broadcast to
     * @param scheduler the task scheduler to use
     */
    public UserRegistryMessageHandler(MultiServerUserRegistry userRegistry, SimpMessagingTemplate brokerTemplate, String broadcastDestination, TaskScheduler scheduler) {
        replacedert.notNull(userRegistry, "'userRegistry' is required");
        replacedert.notNull(brokerTemplate, "'brokerTemplate' is required");
        replacedert.hasText(broadcastDestination, "'broadcastDestination' is required");
        replacedert.notNull(scheduler, "'scheduler' is required");
        this.userRegistry = userRegistry;
        this.brokerTemplate = brokerTemplate;
        this.broadcastDestination = broadcastDestination;
        this.scheduler = scheduler;
    }

    /**
     * Return the configured destination for broadcasting UserRegistry information.
     */
    public String getBroadcastDestination() {
        return this.broadcastDestination;
    }

    /**
     * Configure the amount of time (in milliseconds) before a remote user
     * registry snapshot is considered expired.
     * <p>By default this is set to 20 seconds (value of 20000).
     * @param milliseconds the expiration period in milliseconds
     */
    @SuppressWarnings("unused")
    public void setRegistryExpirationPeriod(long milliseconds) {
        this.registryExpirationPeriod = milliseconds;
    }

    /**
     * Return the configured registry expiration period.
     */
    public long getRegistryExpirationPeriod() {
        return this.registryExpirationPeriod;
    }

    @Override
    public void onApplicationEvent(BrokerAvailabilityEvent event) {
        if (event.isBrokerAvailable()) {
            long delay = getRegistryExpirationPeriod() / 2;
            this.scheduledFuture = this.scheduler.scheduleWithFixedDelay(this.schedulerTask, delay);
        } else {
            ScheduledFuture<?> future = this.scheduledFuture;
            if (future != null) {
                future.cancel(true);
                this.scheduledFuture = null;
            }
        }
    }

    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
        MessageConverter converter = this.brokerTemplate.getMessageConverter();
        this.userRegistry.addRemoteRegistryDto(message, converter, getRegistryExpirationPeriod());
    }

    private clreplaced UserRegistryTask implements Runnable {

        @Override
        public void run() {
            try {
                SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
                accessor.setHeader(SimpMessageHeaderAccessor.IGNORE_ERROR, true);
                accessor.setLeaveMutable(true);
                Object payload = userRegistry.getLocalRegistryDto();
                brokerTemplate.convertAndSend(getBroadcastDestination(), payload, accessor.getMessageHeaders());
            } finally {
                userRegistry.purgeExpiredRegistries();
            }
        }
    }
}

19 View Source File : Communication.java
License : Apache License 2.0
Project Creator : ververica

@Slf4j
@Component
public clreplaced Communication implements PreplacedengerMessaging, DriverMessaging {

    private final KafkaPreplacedengerPublisher preplacedengerPublisher;

    private final KafkaDriverPublisher driverPublisher;

    private final SimpMessagingTemplate simpSender;

    private final String preplacedengerWebSocketTopic;

    private final String driverWebSocketTopic;

    private final ObjectMapper objectMapper = new ObjectMapper();

    private final Scheduler scheduler;

    @Autowired
    public Communication(KafkaPreplacedengerPublisher preplacedengerPublisher, KafkaDriverPublisher driverPublisher, SimpMessagingTemplate simpSender, @Value("${web-socket.topic.preplacedenger}") String preplacedengerWebSocketTopic, @Value("${web-socket.topic.driver}") String driverWebSocketTopic, Scheduler scheduler) {
        this.preplacedengerPublisher = Objects.requireNonNull(preplacedengerPublisher);
        this.driverPublisher = Objects.requireNonNull(driverPublisher);
        this.simpSender = Objects.requireNonNull(simpSender);
        this.preplacedengerWebSocketTopic = Objects.requireNonNull(preplacedengerWebSocketTopic);
        this.driverWebSocketTopic = Objects.requireNonNull(driverWebSocketTopic);
        this.scheduler = Objects.requireNonNull(scheduler);
    }

    public void incomingPreplacedengerEvent(OutboundPreplacedengerMessage message) {
        scheduler.enqueueTaskMessage(message.getPreplacedengerId(), message);
    }

    public void incomingDriverEvent(OutboundDriverMessage message) {
        scheduler.enqueueTaskMessage(message.getDriverId(), message);
    }

    public void outgoingPreplacedengerEvent(InboundPreplacedengerMessage message) {
        preplacedengerPublisher.accept(message);
    }

    public void outgoingDriverEvent(InboundDriverMessage message) {
        driverPublisher.accept(message);
    }

    public void broadcastPreplacedengerSimulationEvent(WebsocketPreplacedengerEvent preplacedengerEvent) {
        String json = toJsonString(preplacedengerEvent);
        simpSender.convertAndSend(preplacedengerWebSocketTopic, json);
    }

    public void broadcastDriverSimulationEvent(WebsocketDriverEvent driverEvent) {
        if (driverEvent.getDriverStatus() == WebsocketDriverEvent.DriverStatus.IDLE) {
            // don't broadcast idle drivers, this is slightly too much.
            return;
        }
        String json = toJsonString(driverEvent);
        simpSender.convertAndSend(driverWebSocketTopic, json);
    }

    private String toJsonString(Object what) {
        try {
            return objectMapper.writeValuereplacedtring(what);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

19 View Source File : FileUploadControllerTest.java
License : Apache License 2.0
Project Creator : usdot-jpo-ode

public clreplaced FileUploadControllerTest {

    FileUploadController testFileUploadController;

    @Mocked
    StorageService mockStorageService;

    @Injectable
    OdeProperties injectableOdeProperties;

    @Injectable
    SimpMessagingTemplate injectableSimpMessagingTemplate;

    @Capturing
    Executors capturingExecutors;

    @Capturing
    ImporterDirectoryWatcher capturingImporterDirectoryWatcher;

    @Mocked
    ExecutorService mockExecutorService;

    @Mocked
    OdeProperties mockOdeProperties;

    @Mocked
    MultipartFile mockMultipartFile;

    @Before
    public void constructorShouldLaunchSevenThreads() {
        new Expectations() {

            {
                mockOdeProperties.getUploadLocationRoot();
                result = "testRootDir";
                mockOdeProperties.getUploadLocationObuLog();
                result = "testLogFileDir";
                Executors.newCachedThreadPool();
                result = mockExecutorService;
                mockExecutorService.submit((Runnable) any);
                times = 7;
            }
        };
        testFileUploadController = new FileUploadController(mockStorageService, mockOdeProperties, injectableSimpMessagingTemplate);
    }

    @Test
    public void handleFileUploadReturnsErrorOnStorageException() {
        new Expectations() {

            {
                mockStorageService.store((MultipartFile) any, anyString);
                result = new StorageFileNotFoundException("testException123");
            }
        };
        replacedertEquals(HttpStatus.BAD_REQUEST, testFileUploadController.handleFileUpload(mockMultipartFile, "type").getStatusCode());
    }

    @Test
    public void successfulUploadReturnsHttpOk() {
        new Expectations() {

            {
                mockStorageService.store((MultipartFile) any, anyString);
                times = 1;
            }
        };
        replacedertEquals(HttpStatus.OK, testFileUploadController.handleFileUpload(mockMultipartFile, "type").getStatusCode());
    }

    @Test
    public void testStorageFileNotFoundException() {
        replacedertEquals(HttpStatus.NOT_FOUND, testFileUploadController.handleStorageFileNotFound(new StorageFileNotFoundException("testException123")).getStatusCode());
    }
}

19 View Source File : StompStringMessageDistributorTest.java
License : Apache License 2.0
Project Creator : usdot-jpo-ode

@Test
public void shouldConstructAndConvertAndSend(@Injectable SimpMessagingTemplate mockSimpMessagingTemplate, @Injectable ConsumerRecord<String, String> mockConsumerRecord) {
    String testTopic = "testTopic123";
    new Expectations() {

        {
            mockSimpMessagingTemplate.convertAndSend(testTopic, (StompContent) any);
            mockConsumerRecord.value();
            result = anyString;
        }
    };
    StompStringMessageDistributor testSSNMP = new StompStringMessageDistributor(mockSimpMessagingTemplate, testTopic);
    testSSNMP.setRecord(mockConsumerRecord);
    try {
        replacedertNull(testSSNMP.call());
    } catch (Exception e) {
        fail("Unexpected exception: " + e);
    }
}

19 View Source File : StompStringExporterTest.java
License : Apache License 2.0
Project Creator : usdot-jpo-ode

public clreplaced StompStringExporterTest {

    @Tested
    StompStringExporter testStompExporter;

    @Injectable
    OdeProperties injectableOdeProperties;

    @Injectable
    String stompTopic = "testTopic";

    @Injectable
    SimpMessagingTemplate simpMessagingTemplate;

    @Injectable
    String odeTopic;

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Test
    public void testSubscribe(@Capturing MessageConsumer capturingMessageConsumer, @Mocked MessageConsumer mockMessageConsumer) {
        new Expectations() {

            {
                MessageConsumer.defaultStringMessageConsumer(anyString, anyString, (MessageProcessor) any);
                result = mockMessageConsumer;
                mockMessageConsumer.setName(anyString);
                times = 1;
                mockMessageConsumer.subscribe(anyString);
                times = 1;
            }
        };
        testStompExporter.subscribe();
    }
}

19 View Source File : ExporterTest.java
License : Apache License 2.0
Project Creator : usdot-jpo-ode

@Test
public void shouldRun(@Mocked OdeProperties mockOdeProperties, @Injectable SimpMessagingTemplate mockSimpMessagingTemplate, @Mocked final MessageConsumer<String, byte[]> mockByteArrayConsumer, @Mocked final MessageConsumer<String, String> mockStringConsumer) {
    String testTopic = "testTopic123";
    new Expectations() {

        {
            mockOdeProperties.getKafkaBrokers();
            result = anyString;
            mockOdeProperties.getHostId();
            result = anyString;
            mockStringConsumer.close();
        }
    };
    try {
        Exporter odeBsmExporter = new StompStringExporter(mockOdeProperties, testTopic, mockSimpMessagingTemplate, "odeTopic");
        odeBsmExporter.setConsumer(mockStringConsumer);
        odeBsmExporter.run();
        Exporter exporter = new Exporter("testTopic") {

            @Override
            protected void subscribe() {
                ;
            }
        };
        exporter.run();
        replacedertNull(exporter.getConsumer());
        replacedertEquals("testTopic", exporter.getTopic());
        exporter = new Exporter("topic", null) {

            @Override
            protected void subscribe() {
                ;
            }
        };
        exporter.run();
        replacedertNull(exporter.getConsumer());
        replacedertEquals("topic", exporter.getTopic());
        exporter.setTopic("topic2");
        replacedertEquals("topic2", exporter.getTopic());
    } catch (Exception e) {
        fail("Unexpected exception: " + e);
    }
}

19 View Source File : StompController.java
License : Apache License 2.0
Project Creator : usdot-jpo-ode

@Controller
public clreplaced StompController {

    @Autowired
    private SimpMessagingTemplate template;

    @MessageMapping("/connect")
    @SendTo("/topic/StompContent")
    public StompContent greeting(RegistrationMessage message) throws InterruptedException {
        // simulated delay
        Thread.sleep(10);
        return new StompContent(message.getName());
    }

    @PostMapping(value = "/newMessage")
    @ResponseBody
    public String messages() {
        template.convertAndSend("/topic/messages", new StompContent("test"));
        return "{\"success\": true}";
    }

    @GetMapping("/")
    public String test() {
        return "index";
    }
}

19 View Source File : StompStringMessageDistributor.java
License : Apache License 2.0
Project Creator : usdot-jpo-ode

public clreplaced StompStringMessageDistributor extends AbstractSubscriberProcessor<String, String> {

    private static Logger logger = LoggerFactory.getLogger(StompStringMessageDistributor.clreplaced);

    private SimpMessagingTemplate template;

    private String topic;

    public StompStringMessageDistributor(SimpMessagingTemplate template, String topic) {
        this.template = template;
        this.topic = topic;
        logger.info("Distributing messages to API layer topic {}", topic);
    }

    @Override
    protected Object process(String consumedData) {
        template.convertAndSend(topic, new StompContent(consumedData));
        return null;
    }
}

19 View Source File : StompStringExporter.java
License : Apache License 2.0
Project Creator : usdot-jpo-ode

/**
 * Created by anthonychen on 10/16/17.
 */
public clreplaced StompStringExporter extends Exporter {

    private OdeProperties odeProperties;

    private SimpMessagingTemplate template;

    private String odeTopic;

    public StompStringExporter(OdeProperties odeProperties, String stompTopic, SimpMessagingTemplate template, String odeTopic) {
        super(stompTopic);
        this.odeProperties = odeProperties;
        this.template = template;
        this.odeTopic = odeTopic;
    }

    @Override
    protected void subscribe() {
        setConsumer(MessageConsumer.defaultStringMessageConsumer(odeProperties.getKafkaBrokers(), odeProperties.getHostId() + this.getClreplaced().getSimpleName(), new StompStringMessageDistributor(template, getTopic())));
        getConsumer().setName(this.getClreplaced().getSimpleName());
        getConsumer().subscribe(odeTopic);
    }
}

19 View Source File : WebSocketController.java
License : Apache License 2.0
Project Creator : turoDog

/**
 * Project Name:springboot_websocket_demo <br/>
 * Package Name:com.nasus.websocket.controller <br/>
 * Date:2019/3/4 22:16 <br/>
 * <b>Description:</b> TODO: 描述该类的作用 <br/>
 *
 * @author <a href="[email protected]">nasus</a><br/>
 * Copyright Notice =========================================================
 * This file contains proprietary information of Eastcom Technologies Co. Ltd.
 * Copying or reproduction without prior written approval is prohibited.
 * Copyright (c) 2019 =======================================================
 */
@RestController
public clreplaced WebSocketController {

    @Autowired
    private SimpMessagingTemplate // 使用 SimpMessagingTemplate 向浏览器发送信息
    messagingTemplate;

    // @MessageMapping 和 @RequestMapping 功能类似,浏览器向服务器发起请求时,映射到该地址。
    @MessageMapping("/hello")
    // 如果服务器接受到了消息,就会对订阅了 @SendTo 括号中的地址的浏览器发送消息。
    @SendTo("/nasus/getResponse")
    public Server2ClientMessage say(Client2ServerMessage message) throws Exception {
        Thread.sleep(3000);
        return new Server2ClientMessage("Hello," + message.getName() + "!");
    }

    @MessageMapping("/chat")
    public void handleChat(Principal principal, String msg) {
        // 在 SpringMVC 中,可以直接在参数中获得 principal,principal 中包含当前用户信息
        if (principal.getName().equals("nasus")) {
            // 硬编码,如果发送人是 nasus 则接收人是 chenzy 反之也成立。
            // 通过 messageingTemplate.convertAndSendToUser 方法向用户发送信息,参数一是接收消息用户,参数二是浏览器订阅地址,参数三是消息本身
            messagingTemplate.convertAndSendToUser("chenzy", "/queue/notifications", principal.getName() + "-send:" + msg);
        } else {
            messagingTemplate.convertAndSendToUser("nasus", "/queue/notifications", principal.getName() + "-send:" + msg);
        }
    }
}

19 View Source File : RecordSender.java
License : MIT License
Project Creator : Toparvion

/**
 * A service for sending main payload - log records - to clients.
 *
 * @author Toparvion
 * @since v0.7
 */
@Service
public clreplaced RecordSender {

    private static final Logger log = LoggerFactory.getLogger(RecordSender.clreplaced);

    private final RecordLevelDetector recordLevelDetector;

    private final SimpMessagingTemplate messagingTemplate;

    private final ColorPicker colorPicker;

    @Autowired
    public RecordSender(RecordLevelDetector recordLevelDetector, SimpMessagingTemplate messagingTemplate, ColorPicker colorPicker) {
        this.recordLevelDetector = recordLevelDetector;
        this.messagingTemplate = messagingTemplate;
        this.colorPicker = colorPicker;
    }

    void sendRecord(Message<?> recordMessage) {
        String destination = recordMessage.getHeaders().get(CLIENT_DESTINATION__HEADER, String.clreplaced);
        String sourceNode = recordMessage.getHeaders().get(SOURCE_NODE__HEADER, String.clreplaced);
        String sourcePath = requireNonNull(recordMessage.getHeaders().get(ORIGINAL_FILE, File.clreplaced)).getAbsolutePath();
        String level = recordMessage.getHeaders().get(RECORD_LEVEL__HEADER, String.clreplaced);
        LocalDateTime timestamp = recordMessage.getHeaders().get(LOG_TIMESTAMP_VALUE__HEADER, LocalDateTime.clreplaced);
        Object payload = recordMessage.getPayload();
        replacedert.isInstanceOf(Collection.clreplaced, payload);
        @SuppressWarnings("unchecked")
        List<String> payloadAsList = new ArrayList<>((Collection<String>) payload);
        // much like with log config entry, the absence of timestamp means that the payload is a flat list of records
        boolean isFlatMessage = (timestamp == null);
        List<StyledLine> styledLines = isFlatMessage ? prepareFlatMessage(payloadAsList) : prepareGroupMessage(payloadAsList, level);
        if (log.isTraceEnabled()) {
            log.trace("Fragment being sent:\n{}", styledLines.stream().map(rec -> String.format("%7s: %s", rec.getStyle(), rec.getText())).collect(joining("\n")));
        }
        LinesPart linesPart;
        if (isFlatMessage) {
            linesPart = new LinesPart(styledLines);
        } else {
            long timestampMillis = timestamp.toInstant(ZoneOffset.UTC).toEpochMilli();
            String highlightColor = colorPicker.pickColor(sourcePath, sourceNode, destination);
            linesPart = new CompositeLinesPart(styledLines, sourceNode, sourcePath, timestampMillis, highlightColor);
        }
        messagingTemplate.convertAndSend(WEBSOCKET_TOPIC_PREFIX + destination, linesPart, singletonMap(MESSAGE_TYPE_HEADER, MessageType.RECORD));
    }

    /*private*/
    List<StyledLine> prepareGroupMessage(List<String> payloadAsList, String firstLineLevel) {
        List<StyledLine> parsedLines = new ArrayList<>();
        if (payloadAsList.isEmpty()) {
            return parsedLines;
        }
        // самую первую строку записи обрабатываем отдельно, так как только она содержит метку уровня
        String firstLine = replacedogUtils.distinguishXml4Group(payloadAsList, 0);
        if (isXmlPrefixed(firstLine)) {
            throw new IllegalStateException(format("The very first line of the record is distinguished as XML but it " + "must contain timestamp only: '%s'", firstLine));
        }
        parsedLines.add(new StyledLine(replacedogUtils.escapeSpecialCharacters(firstLine), firstLineLevel));
        // остальные проверяем в цикле и проставляем им либо XML, либо PLAIN, так как других уровней быть не должно
        for (int i = 1; i < payloadAsList.size(); i++) {
            // check the line for the presence of XML
            String curLine = replacedogUtils.distinguishXml4Group(payloadAsList, i);
            // вставляем текст строки
            String text = replacedogUtils.escapeSpecialCharacters(curLine);
            // определяем и вставляем уровень важности сообщения
            String style;
            if (isXmlPrefixed(text)) {
                style = "XML";
                text = stripXmlPrefix(text);
            } else {
                style = PLAIN_RECORD_LEVEL_NAME;
            }
            // завершаем оформление текущей строки
            parsedLines.add(new StyledLine(text, style));
        }
        return parsedLines;
    }

    /*private*/
    List<StyledLine> prepareFlatMessage(List<String> payloadAsList) {
        List<StyledLine> parsedLines = new ArrayList<>();
        for (int i = 0; i < payloadAsList.size(); i++) {
            // check the line for the presence of XML
            String curLine = replacedogUtils.distinguishXml(payloadAsList, i);
            // insert the text of the line
            String text = replacedogUtils.escapeSpecialCharacters(curLine);
            // detect and set the importance level of the line (this also may appear an XML line)
            String style = recordLevelDetector.detectLevel(curLine).orElseGet(() -> replacedogUtils.checkIfXml(curLine));
            // finish current line construction
            parsedLines.add(new StyledLine(text, style));
        }
        return parsedLines;
    }

    private boolean isXmlPrefixed(String text) {
        return text.startsWith("__XML__");
    }

    private String stripXmlPrefix(String text) {
        return text.substring("__XML__".length());
    }
}

19 View Source File : RssLoadService.java
License : MIT License
Project Creator : tarpha

@Service
@Slf4j
public clreplaced RssLoadService {

    @Autowired
    private RssListRepository rssListRepository;

    @Autowired
    private RssFeedRepository rssFeedRepository;

    @Autowired
    private WatchListRepository watchListRepository;

    @Autowired
    private SeenListRepository seenListRepository;

    @Autowired
    private SettingRepository settingRepository;

    @Autowired
    private DownloadListRepository downloadListRepository;

    @Autowired
    private DownloadPathRepository downloadPathRepository;

    @Autowired
    private TransmissionService transmissionService;

    @Autowired
    private HttpDownloadService httpDownloadService;

    @Autowired
    private DownloadStationService downloadStationService;

    @Autowired
    private DaumMovieTvService daumMovieTvService;

    @Autowired
    private RssMakeService rssMakeService;

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    public void loadRss() {
        log.info("=== Load RSS ===");
        deleteFeed();
        List<RssFeed> rssFeedList = new ArrayList<RssFeed>();
        for (RssFeed rssFeed : rssMakeService.makeRss()) {
            if (!rssFeedRepository.findByLink(rssFeed.getLink()).isPresent()) {
                rssFeedList.add(rssFeed);
                Optional<RssList> optioalRss = rssListRepository.findByName(rssFeed.getRssSite());
                if (optioalRss.isPresent()) {
                    if (optioalRss.get().getDownloadAll()) {
                        download(rssFeed, optioalRss.get());
                    }
                }
                // Watch List를 체크하여 다운로드 요청한다.
                checkWatchList(rssFeed, null);
            }
        }
        for (RssList rss : rssListRepository.findByUseDbAndInternal(true, false)) {
            log.info("Load RSS Site : " + rss.getName());
            try {
                URL feedSource = new URL(rss.getUrl());
                SyndFeedInput input = new SyndFeedInput();
                SyndFeed feedList = input.build(new XmlReader(feedSource));
                for (int i = feedList.getEntries().size() - 1; i >= 0; i--) {
                    // Feed 한 건이 오류가 발생하여도 전체 로드에는 문제 없도록 예외처리를 추가한다.
                    try {
                        SyndEntry feed = feedList.getEntries().get(i);
                        RssFeed rssFeed = new RssFeed();
                        // log.debug(feed.toString());
                        if (!rssFeedRepository.findByLink(rssFeed.getLinkByKey(rss.getLinkKey(), feed)).isPresent()) {
                            rssFeed.setreplacedle(feed.getreplacedle());
                            rssFeed.setRssSite(rss.getName());
                            rssFeed.setTvSeries(rss.getTvSeries());
                            rssFeed.setRssreplacedleByreplacedle(feed.getreplacedle());
                            rssFeed.setRssEpisodeByreplacedle(feed.getreplacedle());
                            rssFeed.setRssSeasonByreplacedle(feed.getreplacedle());
                            rssFeed.setRssQualityByreplacedle(feed.getreplacedle());
                            rssFeed.setRssReleaseGroupByreplacedle(feed.getreplacedle());
                            rssFeed.setRssDateByreplacedle(feed.getreplacedle());
                            rssFeed.setLinkByKey(rss.getLinkKey(), feed);
                            try {
                                if (!StringUtils.isEmpty(feed.getDescription().getValue())) {
                                    rssFeed.setDesc(feed.getDescription().getValue());
                                }
                            } catch (NullPointerException ne) {
                                log.debug("description: " + ne.toString());
                            }
                            String[] rssreplacedleSplit = StringUtils.split(rssFeed.getRssreplacedle());
                            if (rssreplacedleSplit.length == 1) {
                                rssFeed.setRssPoster(daumMovieTvService.getPoster(rssFeed.getRssreplacedle()));
                            } else {
                                for (int j = rssreplacedleSplit.length - 1; j > 0; j--) {
                                    StringBuffer posterreplacedle = new StringBuffer();
                                    for (int k = 0; k <= j; k++) {
                                        posterreplacedle.append(rssreplacedleSplit[k] + " ");
                                    }
                                    String posterUrl = daumMovieTvService.getPoster(StringUtils.trim(posterreplacedle.toString()));
                                    if (!StringUtils.isEmpty(posterUrl)) {
                                        rssFeed.setRssPoster(posterUrl);
                                        break;
                                    }
                                }
                            }
                            // rssFeed.setRssPoster(daumMovieTvService.getPoster(rssFeed.getRssreplacedle()));
                            rssFeedList.add(rssFeed);
                            log.debug("Add Feed: " + rssFeed.getreplacedle());
                            if (rss.getDownloadAll()) {
                                log.debug("RSS Download Repuest All: " + rssFeed.getreplacedle());
                                download(rssFeed, rss);
                            }
                            // Watch List를 체크하여 다운로드 요청한다.
                            checkWatchList(rssFeed, null);
                        }
                    } catch (Exception e) {
                        // Feed 개별 건에 대한 Exception 처리
                        log.error(e.getMessage());
                    }
                }
            } catch (Exception e) {
                // Feed Site에 대한 Exception 처리
                log.error(e.getMessage());
            }
        }
        rssFeedRepository.saveAll(rssFeedList);
        // rssFeedRepository.saveAll(rssMakeService.makeRss());
        simpMessagingTemplate.convertAndSend("/topic/feed/update", true);
    }

    public void checkWatchListFromDb(List<WatchList> list) {
        for (RssFeed rssFeed : rssFeedRepository.findAll()) {
            checkWatchList(rssFeed, list);
        }
    }

    @Async
    public void asyncLoadRss() {
        loadRss();
    }

    public boolean checkWatchListQuality(RssFeed rssFeed, WatchList watchList) {
        boolean checkQuality = false;
        if (StringUtils.isBlank(watchList.getQuality())) {
            watchList.setQuality("100p");
        }
        try {
            if (StringUtils.contains(watchList.getQuality(), ',')) {
                checkQuality = StringUtils.containsIgnoreCase(watchList.getQuality(), rssFeed.getRssQuality());
            } else if (StringUtils.endsWithIgnoreCase(watchList.getQuality(), "P+")) {
                checkQuality = Integer.parseInt(StringUtils.removeIgnoreCase(rssFeed.getRssQuality(), "P")) >= Integer.parseInt(StringUtils.removeIgnoreCase(watchList.getQuality(), "P+"));
            } else {
                checkQuality = Integer.parseInt(StringUtils.removeIgnoreCase(rssFeed.getRssQuality(), "P")) == Integer.parseInt(StringUtils.removeIgnoreCase(watchList.getQuality(), "P"));
            }
        } catch (NumberFormatException e) {
            log.error(e.getMessage());
        }
        return checkQuality;
    }

    /**
     * Feed가 WatchList에 존재할 경우 다운로드 요청을 한다.
     *
     * @param rssFeed   WatchList에 존재하는지 검사할 대상이 되는 개별 RSS Feed
     * @param list      사용자가 화면에서 WatchList 개별 건을 선택해서 직접 실행 했을 때 그 List를 받아올 인자
     */
    private void checkWatchList(RssFeed rssFeed, List<WatchList> list) {
        if (StringUtils.isBlank(rssFeed.getRssQuality())) {
            rssFeed.setRssQuality("100p");
        }
        Optional<WatchList> optionalWatchList = watchListRepository.findByreplacedleRegex(rssFeed.getreplacedle(), rssFeed.getRssQuality());
        if (optionalWatchList.isPresent()) {
            WatchList watchList = optionalWatchList.get();
            log.info("Matched Feed: " + rssFeed.getreplacedle());
            rssFeed.sereplacedchreplacedle(watchList.getreplacedle());
            try {
                if (watchList.getRssList() != null && watchList.getRssList().size() > 0) {
                    if (!watchList.getRssList().contains(rssFeed.getRssSite())) {
                        log.info("Skipped by RSS List");
                        return;
                    }
                }
            } catch (NullPointerException e) {
                log.error(e.toString());
            }
            if (list != null) {
                log.info("Custom Execute");
                boolean isExists = false;
                for (WatchList wl : list) {
                    if (StringUtils.equals(watchList.getreplacedle(), wl.getreplacedle())) {
                        log.info("Custom Execute Matched: " + rssFeed.getreplacedle());
                        isExists = true;
                        break;
                    }
                }
                if (!isExists) {
                    log.info("Custom Execute Not Matched: " + rssFeed.getreplacedle());
                    return;
                }
            }
            boolean seenDone = false;
            boolean subreplacedleDone = false;
            // boolean checkQuality = false;
            // if (StringUtils.isBlank(watchList.getQuality())) {
            // watchList.setQuality("100p");
            // }
            // try {
            // if (StringUtils.endsWithIgnoreCase(watchList.getQuality(), "P+")) {
            // checkQuality = Integer.parseInt(StringUtils.removeIgnoreCase(rssFeed.getRssQuality(), "P"))
            // >= Integer.parseInt(StringUtils.removeIgnoreCase(watchList.getQuality(), "P+"));
            // } else {
            // checkQuality = Integer.parseInt(StringUtils.removeIgnoreCase(rssFeed.getRssQuality(), "P"))
            // == Integer.parseInt(StringUtils.removeIgnoreCase(watchList.getQuality(), "P"));
            // }
            // } catch (NumberFormatException e) {
            // log.error(e.getMessage());
            // }
            // if (!checkQuality) {
            if (!checkWatchListQuality(rssFeed, watchList)) {
                log.info("Rejected by Quality: " + rssFeed.getreplacedle());
                return;
            }
            if (watchList.getSeries()) {
                if (StringUtils.contains(watchList.getQuality(), ',')) {
                    // if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason(),
                    if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.gereplacedchreplacedle(), rssFeed.getRssSeason(), rssFeed.getRssEpisode(), false, rssFeed.getRssQuality()) > 0) {
                        seenDone = true;
                    }
                    // if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason(),
                    if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.gereplacedchreplacedle(), rssFeed.getRssSeason(), rssFeed.getRssEpisode(), true, rssFeed.getRssQuality()) > 0 || !watchList.getSubreplacedle()) {
                        subreplacedleDone = true;
                    }
                } else {
                    // if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason(),
                    if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.gereplacedchreplacedle(), rssFeed.getRssSeason(), rssFeed.getRssEpisode(), false) > 0) {
                        seenDone = true;
                    }
                    // if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason(),
                    if (seenListRepository.countByParams(rssFeed.getLink(), rssFeed.gereplacedchreplacedle(), rssFeed.getRssSeason(), rssFeed.getRssEpisode(), true) > 0 || !watchList.getSubreplacedle()) {
                        subreplacedleDone = true;
                    }
                }
            } else {
                if (seenListRepository.findFirstByLinkAndSubreplacedle(rssFeed.getLink(), false).isPresent()) {
                    seenDone = true;
                }
                if (seenListRepository.findFirstByLinkAndSubreplacedle(rssFeed.getLink(), true).isPresent() || !watchList.getSubreplacedle()) {
                    subreplacedleDone = true;
                }
            }
            if (seenDone && subreplacedleDone) {
                log.info("Rejected by Seen: " + rssFeed.getreplacedle());
            } else {
                if (!watchList.getSubreplacedle() && StringUtils.contains(rssFeed.getreplacedle(), "자막") && !StringUtils.startsWith(rssFeed.getLink(), "magnet")) {
                    log.info("Rejected by Subreplacedle: " + rssFeed.getreplacedle());
                    return;
                }
                if (watchList.getSeries()) {
                    try {
                        int startSeason = Integer.parseInt(watchList.getStartSeason());
                        int endSeason = Integer.parseInt(watchList.getEndSeason());
                        int startEpisode = Integer.parseInt(watchList.getStartEpisode());
                        int endEpisode = Integer.parseInt(watchList.getEndEpisode());
                        int currSeason = Integer.parseInt(rssFeed.getRssSeason());
                        int currEpisode = Integer.parseInt(rssFeed.getRssEpisode());
                        if (currSeason < startSeason || currSeason > endSeason) {
                            log.info("Rejected by Season: Start: " + startSeason + " End: " + endSeason + " Feed: " + currSeason);
                            return;
                        }
                        if (currEpisode < startEpisode || currEpisode > endEpisode) {
                            log.info("Rejected by Episode: Start: " + startEpisode + " End: " + endEpisode + " Feed: " + currEpisode);
                            return;
                        }
                    } catch (NumberFormatException e) {
                        log.error(e.toString());
                    }
                }
                log.info("Download Repuest: " + rssFeed.getreplacedle());
                download(rssFeed, watchList);
            }
        }
    }

    private void addToSeenList(RssFeed rssFeed, String path, String rename) {
        SeenList seenList = new SeenList();
        // seenList.setreplacedle(rssFeed.getRssreplacedle());
        seenList.setreplacedle(rssFeed.gereplacedchreplacedle());
        seenList.setLink(rssFeed.getLink());
        seenList.setDownloadPath(path);
        seenList.setSeason(rssFeed.getRssSeason());
        seenList.setEpisode(rssFeed.getRssEpisode());
        seenList.setRenameStatus(StringUtils.isBlank(rename) ? "N/A" : "false");
        seenList.setQuality(rssFeed.getRssQuality());
        if (StringUtils.contains(rssFeed.getreplacedle(), "자막") && !StringUtils.startsWith(rssFeed.getLink(), "magnet")) {
            seenList.setSubreplacedle(true);
            seenList.setreplacedle("[자막]" + rssFeed.getRssreplacedle());
        }
        seenListRepository.save(seenList);
    }

    private void addToDownloadList(Long id, RssFeed rssFeed, WatchList watchList, String path) {
        DownloadList download = new DownloadList();
        download.setId(id);
        download.setName(rssFeed.getreplacedle());
        download.setUri(rssFeed.getLink());
        download.setDownloadPath(path);
        if (!StringUtils.isBlank(watchList.getRename())) {
            download.setRename(CommonUtils.getRename(watchList.getRename(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason(), rssFeed.getRssEpisode(), rssFeed.getRssQuality(), rssFeed.getRssReleaseGroup(), rssFeed.getRssDate()));
        }
        downloadListRepository.save(download);
    }

    private void addToDownloadList(Long id, RssFeed rssFeed, String path) {
        DownloadList download = new DownloadList();
        download.setId(id);
        download.setName(rssFeed.getreplacedle());
        download.setUri(rssFeed.getLink());
        download.setDownloadPath(path);
        downloadListRepository.save(download);
    }

    private void addToDownloadList(DownloadList download, RssFeed rssFeed, WatchList watchList) {
        if (!StringUtils.isBlank(watchList.getRename())) {
            download.setRename(CommonUtils.getRename(watchList.getRename(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason(), rssFeed.getRssEpisode(), rssFeed.getRssQuality(), rssFeed.getRssReleaseGroup(), rssFeed.getRssDate()));
        }
        downloadListRepository.save(download);
    }

    @Transactional
    private void deleteFeed() {
        Optional<Setting> optionalSetting = settingRepository.findByKey("USE_LIMIT");
        if (optionalSetting.isPresent()) {
            if (Boolean.parseBoolean(optionalSetting.get().getValue())) {
                Optional<Setting> limitCnt = settingRepository.findByKey("LIMIT_COUNT");
                if (limitCnt.isPresent()) {
                    int cnt = Integer.parseInt(limitCnt.get().getValue());
                    rssFeedRepository.deleteByLimitCount(cnt);
                    downloadListRepository.deleteByLimitCount(cnt);
                }
            }
        }
    }

    private void download(RssFeed rssFeed, WatchList watchList) {
        String path = downloadPathRepository.computedPath(watchList.getDownloadPath(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason());
        if (StringUtils.isBlank(path)) {
            path = watchList.getDownloadPath();
        }
        Optional<Setting> optionalSetting = settingRepository.findByKey("DOWNLOAD_APP");
        if (optionalSetting.isPresent()) {
            if (StringUtils.equals(optionalSetting.get().getValue(), "TRANSMISSION")) {
                // Request Download to Transmission
                if (StringUtils.startsWith(rssFeed.getLink(), "magnet") || StringUtils.equalsIgnoreCase(FilenameUtils.getExtension(rssFeed.getLink()), "torrent")) {
                    int torrentAddedId = transmissionService.torrentAdd(rssFeed.getLink(), path);
                    log.debug("Transmission ID: " + torrentAddedId);
                    if (torrentAddedId > 0) {
                        // Add to Seen
                        addToSeenList(rssFeed, path, watchList.getRename());
                        // Add to Download List
                        addToDownloadList((long) torrentAddedId, rssFeed, watchList, path);
                    }
                } else {
                    Optional<DownloadList> optionalSeq = downloadListRepository.findTopByOrderByIdDesc();
                    long tempId;
                    if (optionalSeq.isPresent()) {
                        Long id = optionalSeq.get().getId() + 100L;
                        log.debug("id: " + id);
                        tempId = id;
                    } else {
                        tempId = 100L;
                    }
                    DownloadList download = new DownloadList();
                    download.setUri(rssFeed.getLink());
                    download.setDownloadPath(path);
                    download.setId(tempId);
                    httpDownloadService.createTransmission(download);
                    addToSeenList(rssFeed, path, watchList.getRename());
                }
            } else if (StringUtils.equals(optionalSetting.get().getValue(), "DOWNLOAD_STATION")) {
                // Request Download to Download Station
                if (downloadStationService.create(rssFeed.getLink(), path)) {
                    // Add to Seen
                    addToSeenList(rssFeed, path, watchList.getRename());
                    // Add to Download List
                    boolean isExist = false;
                    for (DownloadList down : downloadStationService.list()) {
                        if (StringUtils.equals(rssFeed.getLink(), down.getUri())) {
                            isExist = true;
                            // downloadListRepository.save(down);
                            addToDownloadList(down, rssFeed, watchList);
                        }
                    }
                    if (isExist == false) {
                        addToDownloadList(0L, rssFeed, watchList, path);
                    }
                }
            }
        }
    }

    private void download(RssFeed rssFeed, RssList rssList) {
        String path = downloadPathRepository.computedPath(rssList.getDownloadPath(), rssFeed.getRssreplacedle(), rssFeed.getRssSeason());
        if (StringUtils.isBlank(path)) {
            path = rssList.getDownloadPath();
        }
        Optional<Setting> optionalSetting = settingRepository.findByKey("DOWNLOAD_APP");
        if (optionalSetting.isPresent()) {
            if (StringUtils.equals(optionalSetting.get().getValue(), "TRANSMISSION")) {
                // Request Download to Transmission
                if (StringUtils.startsWith(rssFeed.getLink(), "magnet") || StringUtils.equalsIgnoreCase(FilenameUtils.getExtension(rssFeed.getLink()), "torrent")) {
                    int torrentAddedId = transmissionService.torrentAdd(rssFeed.getLink(), path);
                    log.debug("Transmission ID: " + torrentAddedId);
                    if (torrentAddedId > 0) {
                        // Add to Seen
                        // addToSeenList(rssFeed, path);
                        // Add to Download List
                        addToDownloadList((long) torrentAddedId, rssFeed, path);
                    }
                } else {
                    Optional<DownloadList> optionalSeq = downloadListRepository.findTopByOrderByIdDesc();
                    long tempId;
                    if (optionalSeq.isPresent()) {
                        Long id = optionalSeq.get().getId() + 100L;
                        log.debug("id: " + id);
                        tempId = id;
                    } else {
                        tempId = 100L;
                    }
                    DownloadList download = new DownloadList();
                    download.setUri(rssFeed.getLink());
                    download.setDownloadPath(path);
                    download.setId(tempId);
                    httpDownloadService.createTransmission(download);
                }
            } else if (StringUtils.equals(optionalSetting.get().getValue(), "DOWNLOAD_STATION")) {
                // Request Download to Download Station
                if (downloadStationService.create(rssFeed.getLink(), path)) {
                    // Add to Seen
                    // addToSeenList(rssFeed, path);
                    // Add to Download List
                    boolean isExist = false;
                    for (DownloadList down : downloadStationService.list()) {
                        if (StringUtils.equals(rssFeed.getLink(), down.getUri())) {
                            isExist = true;
                            downloadListRepository.save(down);
                        }
                    }
                    if (isExist == false) {
                        addToDownloadList(0L, rssFeed, path);
                    }
                }
            }
        }
    }
}

19 View Source File : HttpDownloadService.java
License : MIT License
Project Creator : tarpha

@Service
@Slf4j
public clreplaced HttpDownloadService {

    @Autowired
    private TransmissionService transmissionService;

    @Autowired
    private DownloadListRepository downloadListRepository;

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    private Map<Long, HttpVo> jobs = new HashMap<>();

    @Data
    private clreplaced HttpVo {

        private Long id;

        private String name;

        private String filename;

        private String path;

        private int percentDone = 0;

        private Boolean done = false;
    }

    @Async
    public void createTransmission(DownloadList download) {
        String link = download.getUri();
        String path = download.getDownloadPath();
        long currentId = download.getId();
        try {
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            URIBuilder builder = new URIBuilder(link);
            HttpGet httpGet = new HttpGet(builder.build());
            CloseableHttpResponse response = httpClient.execute(httpGet);
            Header[] header = response.getHeaders("Content-Disposition");
            String content = header[0].getValue();
            for (String str : StringUtils.split(content, ";")) {
                if (StringUtils.containsIgnoreCase(str, "filename=")) {
                    log.debug(str);
                    String[] attachment = StringUtils.split(str, "=");
                    File directory = new File(path);
                    if (!directory.isDirectory()) {
                        FileUtils.forceMkdir(directory);
                    }
                    String filename = StringUtils.remove(attachment[1], "\"");
                    HttpVo vo = new HttpVo();
                    vo.setId(currentId);
                    vo.setName(download.getName());
                    vo.setFilename(filename);
                    vo.setPath(download.getDownloadPath());
                    jobs.put(currentId, vo);
                    download.setFileName(filename);
                    download.setDbid("http_" + vo.getId());
                    downloadListRepository.save(download);
                    BufferedInputStream bis = new BufferedInputStream(response.getEnreplacedy().getContent());
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(path, filename)));
                    int inByte;
                    while ((inByte = bis.read()) != -1) bos.write(inByte);
                    bis.close();
                    bos.close();
                    vo.setDone(true);
                    vo.setPercentDone(100);
                    jobs.put(currentId, vo);
                    downloadListRepository.save(download);
                    // if(StringUtils.equalsIgnoreCase(FilenameUtils.getExtension(attachment[1]), "torrent")) {
                    if (StringUtils.containsIgnoreCase(filename, ".torrent")) {
                        long ret = transmissionService.torrentAdd(path + File.separator + filename, path);
                        if (ret > 0L) {
                            download.setId(ret);
                            downloadListRepository.save(download);
                            simpMessagingTemplate.convertAndSend("/topic/feed/download", download);
                        }
                    }
                }
            }
            response.close();
            httpClient.close();
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    public DownloadList getInfo(Long id) {
        if (jobs.containsKey(id)) {
            DownloadList download = new DownloadList();
            HttpVo vo = jobs.get(id);
            download.setId(vo.getId());
            download.setDbid("http_" + vo.getId());
            download.setPercentDone(vo.getPercentDone());
            download.setDone(vo.getDone());
            download.setDownloadPath(vo.getPath());
            download.setFileName(vo.getFilename());
            download.setName(vo.getName());
            if (vo.getDone()) {
                jobs.remove(vo.getId());
            }
            return download;
        }
        return null;
    }
}

19 View Source File : TodoCollaborationService.java
License : Apache License 2.0
Project Creator : stratospheric-dev

@Service
@Transactional
public clreplaced TodoCollaborationService {

    private final TodoRepository todoRepository;

    private final PersonRepository personRepository;

    private final TodoCollaborationRequestRepository todoCollaborationRequestRepository;

    private final QueueMessagingTemplate queueMessagingTemplate;

    private final String todoSharingQueueName;

    private final SimpMessagingTemplate simpMessagingTemplate;

    private static final Logger LOG = LoggerFactory.getLogger(TodoCollaborationService.clreplaced.getName());

    private static final String INVALID_TODO_ID = "Invalid todo ID: ";

    private static final String INVALID_PERSON_ID = "Invalid person ID: ";

    public TodoCollaborationService(@Value("${custom.sharing-queue}") String todoSharingQueueName, TodoRepository todoRepository, PersonRepository personRepository, TodoCollaborationRequestRepository todoCollaborationRequestRepository, QueueMessagingTemplate queueMessagingTemplate, SimpMessagingTemplate simpMessagingTemplate) {
        this.todoRepository = todoRepository;
        this.personRepository = personRepository;
        this.todoCollaborationRequestRepository = todoCollaborationRequestRepository;
        this.queueMessagingTemplate = queueMessagingTemplate;
        this.todoSharingQueueName = todoSharingQueueName;
        this.simpMessagingTemplate = simpMessagingTemplate;
    }

    public String shareWithCollaborator(String todoOwnerEmail, Long todoId, Long collaboratorId) {
        Todo todo = todoRepository.findByIdAndOwnerEmail(todoId, todoOwnerEmail).orElseThrow(() -> new IllegalArgumentException(INVALID_TODO_ID + todoId));
        Person collaborator = personRepository.findById(collaboratorId).orElseThrow(() -> new IllegalArgumentException(INVALID_PERSON_ID + collaboratorId));
        if (todoCollaborationRequestRepository.findByTodoAndCollaborator(todo, collaborator) != null) {
            LOG.info("Collaboration request for todo {} with collaborator {} already exists", todoId, collaboratorId);
            return collaborator.getName();
        }
        LOG.info("About to share todo with id {} with collaborator {}", todoId, collaboratorId);
        TodoCollaborationRequest collaboration = new TodoCollaborationRequest();
        String token = UUID.randomUUID().toString();
        collaboration.setToken(token);
        collaboration.setCollaborator(collaborator);
        collaboration.setTodo(todo);
        todo.getCollaborationRequests().add(collaboration);
        todoCollaborationRequestRepository.save(collaboration);
        queueMessagingTemplate.convertAndSend(todoSharingQueueName, new TodoCollaborationNotification(collaboration));
        return collaborator.getName();
    }

    public boolean confirmCollaboration(Long todoId, Long collaboratorId, String token) {
        TodoCollaborationRequest collaborationRequest = todoCollaborationRequestRepository.findByTodoIdAndCollaboratorId(todoId, collaboratorId);
        LOG.info("Collaboration request: {}", collaborationRequest);
        if (collaborationRequest != null) {
            LOG.info("Original collaboration token: {}", collaborationRequest.getToken());
            LOG.info("Request token: {}", token);
        }
        if (collaborationRequest != null && collaborationRequest.getToken().equals(token)) {
            Todo todo = todoRepository.findById(todoId).orElseThrow(() -> new IllegalArgumentException(INVALID_TODO_ID + todoId));
            Person collaborator = personRepository.findById(collaboratorId).orElseThrow(() -> new IllegalArgumentException(INVALID_PERSON_ID + collaboratorId));
            todo.addCollaborator(collaborator);
            todoCollaborationRequestRepository.delete(collaborationRequest);
            String name = collaborationRequest.getCollaborator().getName();
            String subject = "Collaboration confirmed.";
            String message = "User " + name + " has accepted your collaboration request for todo #" + collaborationRequest.getTodo().getId() + ".";
            String ownerEmail = collaborationRequest.getTodo().getOwner().getEmail();
            simpMessagingTemplate.convertAndSend("/topic/todoUpdates/" + ownerEmail, subject + " " + message);
            LOG.info("Successfully informed owner about accepted request.");
            return true;
        }
        return false;
    }
}

19 View Source File : CalendarWebSocket.java
License : Apache License 2.0
Project Creator : speedment

/**
 * @author Emil Forslund
 * @since  1.0.0
 */
@Component
public final clreplaced CalendarWebSocket {

    @Autowired
    private BookingView view;

    @Autowired
    private SimpMessagingTemplate template;

    @PostConstruct
    void listenForChanges() {
        view.addAcceptedListener(this::pushNotification);
        view.addRefusedListener(this::pushNotification);
    }

    private void pushNotification(BookingConfirmation notification) {
        template.convertAndSend("/calendar", notification);
    }
}

19 View Source File : WebSocketConsumersManager.java
License : MIT License
Project Creator : SourceLabOrg

/**
 * Manages background kafka consumers and transfers consumed messages from them to their
 * corresponding WebSocket connections.
 */
public clreplaced WebSocketConsumersManager implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketConsumersManager.clreplaced);

    /**
     * Holds a map of ConsumerKey to ConsumerEntry, which is basically a container
     * for the running consumers.
     */
    private final Map<ConsumerKey, ConsumerEntry> consumers = new ConcurrentHashMap<>();

    /**
     * For creating new consumers.
     */
    private final WebKafkaConsumerFactory webKafkaConsumerFactory;

    /**
     * For sending responses to connected client.
     */
    private final SimpMessagingTemplate simpMessagingTemplate;

    /**
     * Thread pool where we run consumers within background threads.
     */
    private final ThreadPoolExecutor threadPoolExecutor;

    /**
     * Constructor.
     * @param webKafkaConsumerFactory For creating new Consumers.
     * @param messagingTemplate For publishing consumed messages back through the web socket.
     * @param maxConcurrentConsumers Configuration, how many consumers to run.
     */
    public WebSocketConsumersManager(final WebKafkaConsumerFactory webKafkaConsumerFactory, final SimpMessagingTemplate messagingTemplate, final int maxConcurrentConsumers) {
        this(webKafkaConsumerFactory, messagingTemplate, // Setup managed thread pool with number of concurrent threads.
        new ThreadPoolExecutor(maxConcurrentConsumers, maxConcurrentConsumers, 5, TimeUnit.MINUTES, new LinkedBlockingQueue<>(100)));
    }

    /**
     * Constructor for injecting a ThreadPoolExecutor.
     *
     * @param webKafkaConsumerFactory For creating new Consumers.
     * @param messagingTemplate For publishing consumed messages back through the web socket.
     * @param threadPoolExecutor executor pool for async processing.
     */
    public WebSocketConsumersManager(final WebKafkaConsumerFactory webKafkaConsumerFactory, final SimpMessagingTemplate messagingTemplate, final ThreadPoolExecutor threadPoolExecutor) {
        this.webKafkaConsumerFactory = webKafkaConsumerFactory;
        this.simpMessagingTemplate = messagingTemplate;
        // TODO add handler for when a new connection comes in that exceeds the maximum running concurrent consumers.
        this.threadPoolExecutor = threadPoolExecutor;
    }

    /**
     * Start up a new consumer for the given view.
     * @param view The view to consume from
     * @param startingPosition What position to resume consuming from.
     * @param sessionIdentifier The user who is consuming.
     */
    public void addNewConsumer(final View view, final Collection<FilterDefinition> filters, final StartingPosition startingPosition, final SessionIdentifier sessionIdentifier) {
        synchronized (consumers) {
            // createWebClient a key
            final ConsumerKey consumerKey = new ConsumerKey(view.getId(), sessionIdentifier);
            if (consumers.containsKey(consumerKey)) {
                // TODO handle better
                throw new RuntimeException("Consumer already exists!");
            }
            // Create consumer
            final SocketKafkaConsumer webKafkaConsumer = webKafkaConsumerFactory.createWebSocketClient(view, filters, startingPosition, sessionIdentifier);
            // Create entry
            final ConsumerEntry consumerEntry = new ConsumerEntry(webKafkaConsumer);
            consumers.put(consumerKey, consumerEntry);
            // Toss into executor
            threadPoolExecutor.execute(webKafkaConsumer);
            // Add logger statement
            logger.info("Added new web socket consumer, now has {}/{} running consumers", threadPoolExecutor.getActiveCount(), threadPoolExecutor.getMaximumPoolSize());
        }
    }

    /**
     * Remove consumer based on their private session id.
     * Typically this is called when a consumer disconnects from the websocket.
     */
    public void removeConsumersForSessionId(final String sessionId) {
        synchronized (consumers) {
            consumers.entrySet().stream().filter((entry) -> entry.getKey().getSessionId().equals(sessionId)).forEach((entry) -> entry.getValue().requestStop());
        }
    }

    /**
     * Remove consumer based on their public session hash.
     * Typically this is called when a request to disconnect a consumer is made by the consumer manager
     * web UI.
     */
    public boolean removeConsumersForSessionHash(final String sessionHash) {
        synchronized (consumers) {
            for (final Map.Entry<ConsumerKey, ConsumerEntry> entry : consumers.entrySet()) {
                if (!entry.getKey().getSessionHash().equals(sessionHash)) {
                    continue;
                }
                entry.getValue().requestStop();
                return true;
            }
        }
        return false;
    }

    /**
     * Pause a consumer.
     */
    public void pauseConsumer(final long viewId, final SessionIdentifier sessionIdentifier) {
        // createWebClient a key
        final ConsumerKey consumerKey = new ConsumerKey(viewId, sessionIdentifier);
        synchronized (consumers) {
            if (!consumers.containsKey(consumerKey)) {
                return;
            }
            // Get entry
            final ConsumerEntry consumerEntry = consumers.get(consumerKey);
            // Lets pause it
            consumerEntry.requestPause();
        }
    }

    /**
     * Resume a consumer.
     */
    public void resumeConsumer(final long viewId, final SessionIdentifier sessionIdentifier) {
        synchronized (consumers) {
            // createWebClient a key
            final ConsumerKey consumerKey = new ConsumerKey(viewId, sessionIdentifier);
            if (!consumers.containsKey(consumerKey)) {
                return;
            }
            // Get entry
            final ConsumerEntry consumerEntry = consumers.get(consumerKey);
            // Lets pause it
            consumerEntry.requestResume();
        }
    }

    /**
     * @return Returns all of the currently active consumers.
     */
    public Collection<StreamConsumerDetails> getConsumers() {
        final Collection<StreamConsumerDetails> details = consumers.entrySet().stream().map((entry) -> new StreamConsumerDetails(entry.getKey().getUserId(), entry.getKey().getViewId(), entry.getKey().getSessionHash(), entry.getValue().getStartTimestamp(), entry.getValue().getRecordCount(), entry.getValue().isPaused())).collect(Collectors.toList());
        // Return immutable
        return Collections.unmodifiableCollection(details);
    }

    /**
     * @return Current number of active consumers.
     */
    public int countActiveConsumers() {
        return consumers.size();
    }

    /**
     * Main processing loop for the Manager.
     */
    @Override
    public void run() {
        // Loop thru consumers, consume, and publish to socket.
        do {
            boolean foundResult = false;
            final List<ConsumerKey> consumerKeysToRemove = new ArrayList<>();
            // Loop over each consumer
            for (final Map.Entry<ConsumerKey, ConsumerEntry> entry : consumers.entrySet()) {
                try {
                    final ConsumerKey consumerKey = entry.getKey();
                    final ConsumerEntry consumerEntry = entry.getValue();
                    if (consumerEntry.isShouldStop()) {
                        // Add to remove list
                        consumerKeysToRemove.add(consumerKey);
                        continue;
                    }
                    // Consume
                    final Optional<KafkaResult> kafkaResult = consumerEntry.nextResult();
                    if (!kafkaResult.isPresent()) {
                        continue;
                    }
                    // Flip flag to true
                    foundResult = true;
                    // publish
                    final String target = "/topic/view/" + consumerKey.getViewId() + "/" + consumerKey.getUserId();
                    // Define header so we can send the message to a specific session id.
                    final SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
                    headerAccessor.setSessionId(consumerKey.getSessionId());
                    headerAccessor.setLeaveMutable(true);
                    // Only send it to the specific user's sesison Id.
                    simpMessagingTemplate.convertAndSendToUser(consumerKey.getSessionId(), target, kafkaResult.get(), headerAccessor.getMessageHeaders());
                } catch (final Exception exception) {
                    // Handle
                    logger.error(exception.getMessage(), exception);
                }
            }
            // Remove any consumers
            for (final ConsumerKey consumerKey : consumerKeysToRemove) {
                consumers.remove(consumerKey);
                // Add logger statement, this isn't completely accurate because the thread
                // may not have shut down yet..
                logger.info("Removed web socket consumer, now has ~ {}/{} running consumers", threadPoolExecutor.getActiveCount(), threadPoolExecutor.getMaximumPoolSize());
            }
            // Throttle with sleep
            if (!foundResult) {
                try {
                    Thread.sleep(500L);
                } catch (final InterruptedException e) {
                    break;
                }
            }
        } while (true);
        // Shut down
        threadPoolExecutor.shutdown();
    }

    /**
     * Small wrapper around the Socket Consumer.
     */
    private static final clreplaced ConsumerEntry {

        /**
         * Our wrapped SocketKafkaConsumer instance.
         */
        private final SocketKafkaConsumer socketKafkaConsumer;

        /**
         * Holds how many records we have consumed.
         */
        private final AtomicLong recordCount = new AtomicLong(0);

        /**
         * Holds when we started consuming.
         */
        private final long startTimestamp = Clock.systemUTC().millis();

        /**
         * Flag if we should requestStop.
         */
        private boolean shouldStop = false;

        /**
         * Flag if we should be paused.
         */
        private AtomicBoolean isPaused = new AtomicBoolean(false);

        /**
         * Constructor.
         * @param socketKafkaConsumer The consumer to wrap.
         */
        public ConsumerEntry(final SocketKafkaConsumer socketKafkaConsumer) {
            this.socketKafkaConsumer = socketKafkaConsumer;
        }

        /**
         * Retrieve the next record from Kafka.
         * @return Optional of KafkaResult.  This could return null if there are no new records to consume.
         */
        public Optional<KafkaResult> nextResult() {
            // If paused
            if (isPaused.get()) {
                // always return false.  This will cause the internal buffer to block
                // on the consumer side.
                return Optional.empty();
            }
            final Optional<KafkaResult> result = socketKafkaConsumer.nextResult();
            // Increment counter if record returned.
            result.ifPresent((record) -> recordCount.incrementAndGet());
            // Return result
            return result;
        }

        /**
         * @return True if a stop has been requested.
         */
        public synchronized boolean isShouldStop() {
            return shouldStop;
        }

        /**
         * Request the Consumer to shutdown/stop.
         */
        public synchronized void requestStop() {
            this.socketKafkaConsumer.requestStop();
            this.shouldStop = true;
        }

        /**
         * Request the consumer to be paused.
         */
        public synchronized void requestPause() {
            isPaused.set(true);
        }

        /**
         * Request the consumer to be resumed.
         */
        public synchronized void requestResume() {
            isPaused.set(false);
        }

        public long getRecordCount() {
            return recordCount.get();
        }

        public long getStartTimestamp() {
            return startTimestamp;
        }

        public boolean isPaused() {
            return isPaused.get();
        }
    }

    /**
     * Represents a unique consumer key.
     * This could probably simplified down to just the sessionId.
     */
    static final clreplaced ConsumerKey {

        // viewId, userId, and sessionId make a unique consumer key.
        private final long viewId;

        private final long userId;

        // Session id should be considered private and should not be shared with other users.
        // TODO probably should deprecate this.
        private final String sessionId;

        // Session hash can be shared publicly to identify a session.
        private final String sessionHash;

        ConsumerKey(final long viewId, final SessionIdentifier sessionIdentifier) {
            this.viewId = viewId;
            this.userId = sessionIdentifier.getUserId();
            this.sessionId = sessionIdentifier.getSessionId();
            this.sessionHash = Sha1Tools.sha1(this.sessionId);
        }

        public long getViewId() {
            return viewId;
        }

        public long getUserId() {
            return userId;
        }

        public String getSessionId() {
            return sessionId;
        }

        public String getSessionHash() {
            return sessionHash;
        }

        @Override
        public boolean equals(final Object other) {
            if (this == other) {
                return true;
            }
            if (other == null || getClreplaced() != other.getClreplaced()) {
                return false;
            }
            final ConsumerKey that = (ConsumerKey) other;
            if (viewId != that.viewId) {
                return false;
            }
            if (userId != that.userId) {
                return false;
            }
            return sessionId.equals(that.sessionId);
        }

        @Override
        public int hashCode() {
            int result = (int) (viewId ^ (viewId >>> 32));
            result = 31 * result + (int) (userId ^ (userId >>> 32));
            result = 31 * result + sessionId.hashCode();
            return result;
        }
    }
}

19 View Source File : ExchangePushJob.java
License : MIT License
Project Creator : sengeiou

@Component
public clreplaced ExchangePushJob {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private NettyHandler nettyHandler;

    private Map<String, List<ExchangeTrade>> tradesQueue = new HashMap<>();

    private Map<String, List<TradePlate>> plateQueue = new HashMap<>();

    private Map<String, List<CoinThumb>> thumbQueue = new HashMap<>();

    public void addTrades(String symbol, List<ExchangeTrade> trades) {
        List<ExchangeTrade> list = tradesQueue.get(symbol);
        if (list == null) {
            list = new ArrayList<>();
            tradesQueue.put(symbol, list);
        }
        synchronized (list) {
            list.addAll(trades);
        }
    }

    public void addPlates(String symbol, TradePlate plate) {
        List<TradePlate> list = plateQueue.get(symbol);
        if (list == null) {
            list = new ArrayList<>();
            plateQueue.put(symbol, list);
        }
        synchronized (list) {
            list.add(plate);
        }
    }

    public void addThumb(String symbol, CoinThumb thumb) {
        List<CoinThumb> list = thumbQueue.get(symbol);
        if (list == null) {
            list = new ArrayList<>();
            thumbQueue.put(symbol, list);
        }
        synchronized (list) {
            list.add(thumb);
        }
    }

    @Scheduled(fixedRate = 500)
    public void pushTrade() {
        Iterator<Map.Entry<String, List<ExchangeTrade>>> entryIterator = tradesQueue.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, List<ExchangeTrade>> entry = entryIterator.next();
            String symbol = entry.getKey();
            List<ExchangeTrade> trades = entry.getValue();
            if (trades.size() > 0) {
                synchronized (trades) {
                    messagingTemplate.convertAndSend("/topic/market/trade/" + symbol, trades);
                    trades.clear();
                }
            }
        }
    }

    @Scheduled(fixedRate = 500)
    public void pushPlate() {
        Iterator<Map.Entry<String, List<TradePlate>>> entryIterator = plateQueue.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, List<TradePlate>> entry = entryIterator.next();
            String symbol = entry.getKey();
            List<TradePlate> plates = entry.getValue();
            if (plates.size() > 0) {
                boolean hasPushAskPlate = false;
                boolean hasPushBidPlate = false;
                synchronized (plates) {
                    for (TradePlate plate : plates) {
                        if (plate.getDirection() == ExchangeOrderDirection.BUY && !hasPushBidPlate) {
                            hasPushBidPlate = true;
                        } else if (plate.getDirection() == ExchangeOrderDirection.SELL && !hasPushAskPlate) {
                            hasPushAskPlate = true;
                        } else {
                            continue;
                        }
                        // websocket推送盘口信息
                        messagingTemplate.convertAndSend("/topic/market/trade-plate/" + symbol, plate.toJSON(24));
                        // websocket推送深度信息
                        messagingTemplate.convertAndSend("/topic/market/trade-depth/" + symbol, plate.toJSON());
                        // netty推送
                        nettyHandler.handlePlate(symbol, plate);
                    }
                    plates.clear();
                }
            }
        }
    }

    @Scheduled(fixedRate = 500)
    public void pushThumb() {
        Iterator<Map.Entry<String, List<CoinThumb>>> entryIterator = thumbQueue.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, List<CoinThumb>> entry = entryIterator.next();
            String symbol = entry.getKey();
            List<CoinThumb> thumbs = entry.getValue();
            if (thumbs.size() > 0) {
                synchronized (thumbs) {
                    messagingTemplate.convertAndSend("/topic/market/thumb", thumbs.get(thumbs.size() - 1));
                    thumbs.clear();
                }
            }
        }
    }
}

19 View Source File : ExchangeTradeConsumer.java
License : MIT License
Project Creator : sengeiou

@Component
@Slf4j
public clreplaced ExchangeTradeConsumer {

    private Logger logger = LoggerFactory.getLogger(ExchangeTradeConsumer.clreplaced);

    @Autowired
    private CoinProcessorFactory coinProcessorFactory;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private ExchangeOrderService exchangeOrderService;

    @Autowired
    private NettyHandler nettyHandler;

    @Value("${second.referrer.award}")
    private boolean secondReferrerAward;

    private ExecutorService executor = new ThreadPoolExecutor(30, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), new ThreadPoolExecutor.AbortPolicy());

    @Autowired
    private ExchangePushJob pushJob;

    /**
     * 处理成交明细
     *
     * @param records
     */
    @KafkaListener(topics = "exchange-trade", containerFactory = "kafkaListenerContainerFactory")
    public void handleTrade(List<ConsumerRecord<String, String>> records) {
        for (int i = 0; i < records.size(); i++) {
            ConsumerRecord<String, String> record = records.get(i);
            executor.submit(new HandleTradeThread(record));
        }
    }

    @KafkaListener(topics = "exchange-order-completed", containerFactory = "kafkaListenerContainerFactory")
    public void handleOrderCompleted(List<ConsumerRecord<String, String>> records) {
        try {
            for (int i = 0; i < records.size(); i++) {
                ConsumerRecord<String, String> record = records.get(i);
                logger.info("订单交易处理完成消息topic={},value={}", record.topic(), record.value());
                List<ExchangeOrder> orders = JSON.parseArray(record.value(), ExchangeOrder.clreplaced);
                for (ExchangeOrder order : orders) {
                    String symbol = order.getSymbol();
                    // 委托成交完成处理
                    exchangeOrderService.tradeCompleted(order.getOrderId(), order.getTradedAmount(), order.getTurnover());
                    // 推送订单成交
                    messagingTemplate.convertAndSend("/topic/market/order-completed/" + symbol + "/" + order.getMemberId(), order);
                    nettyHandler.handleOrder(NettyCommand.PUSH_EXCHANGE_ORDER_COMPLETED, order);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理模拟交易
     *
     * @param records
     */
    @KafkaListener(topics = "exchange-trade-mocker", containerFactory = "kafkaListenerContainerFactory")
    public void handleMockerTrade(List<ConsumerRecord<String, String>> records) {
        try {
            for (int i = 0; i < records.size(); i++) {
                ConsumerRecord<String, String> record = records.get(i);
                logger.info("mock数据topic={},value={},size={}", record.topic(), record.value(), records.size());
                List<ExchangeTrade> trades = JSON.parseArray(record.value(), ExchangeTrade.clreplaced);
                String symbol = trades.get(0).getSymbol();
                // 处理行情
                CoinProcessor coinProcessor = coinProcessorFactory.getProcessor(symbol);
                if (coinProcessor != null) {
                    coinProcessor.process(trades);
                }
                pushJob.addTrades(symbol, trades);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 消费交易盘口信息
     *
     * @param records
     */
    @KafkaListener(topics = "exchange-trade-plate", containerFactory = "kafkaListenerContainerFactory")
    public void handleTradePlate(List<ConsumerRecord<String, String>> records) {
        try {
            for (int i = 0; i < records.size(); i++) {
                ConsumerRecord<String, String> record = records.get(i);
                logger.info("推送盘口信息topic={},value={},size={}", record.topic(), record.value(), records.size());
                TradePlate plate = JSON.parseObject(record.value(), TradePlate.clreplaced);
                String symbol = plate.getSymbol();
                pushJob.addPlates(symbol, plate);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 订单取消成功
     *
     * @param records
     */
    @KafkaListener(topics = "exchange-order-cancel-success", containerFactory = "kafkaListenerContainerFactory")
    public void handleOrderCanceled(List<ConsumerRecord<String, String>> records) {
        try {
            for (int i = 0; i < records.size(); i++) {
                ConsumerRecord<String, String> record = records.get(i);
                logger.info("取消订单消息topic={},value={},size={}", record.topic(), record.value(), records.size());
                ExchangeOrder order = JSON.parseObject(record.value(), ExchangeOrder.clreplaced);
                String symbol = order.getSymbol();
                // 调用服务处理
                exchangeOrderService.cancelOrder(order.getOrderId(), order.getTradedAmount(), order.getTurnover());
                // 推送实时成交
                messagingTemplate.convertAndSend("/topic/market/order-canceled/" + symbol + "/" + order.getMemberId(), order);
                nettyHandler.handleOrder(NettyCommand.PUSH_EXCHANGE_ORDER_CANCELED, order);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public clreplaced HandleTradeThread implements Runnable {

        private ConsumerRecord<String, String> record;

        private HandleTradeThread(ConsumerRecord<String, String> record) {
            this.record = record;
        }

        @Override
        public void run() {
            logger.info("topic={},value={}", record.topic(), record.value());
            try {
                List<ExchangeTrade> trades = JSON.parseArray(record.value(), ExchangeTrade.clreplaced);
                String symbol = trades.get(0).getSymbol();
                CoinProcessor coinProcessor = coinProcessorFactory.getProcessor(symbol);
                for (ExchangeTrade trade : trades) {
                    // 成交明细处理
                    exchangeOrderService.processExchangeTrade(trade, secondReferrerAward);
                    // 推送订单成交订阅
                    ExchangeOrder buyOrder = exchangeOrderService.findOne(trade.getBuyOrderId());
                    ExchangeOrder sellOrder = exchangeOrderService.findOne(trade.getSellOrderId());
                    messagingTemplate.convertAndSend("/topic/market/order-trade/" + symbol + "/" + buyOrder.getMemberId(), buyOrder);
                    messagingTemplate.convertAndSend("/topic/market/order-trade/" + symbol + "/" + sellOrder.getMemberId(), sellOrder);
                    nettyHandler.handleOrder(NettyCommand.PUSH_EXCHANGE_ORDER_TRADE, buyOrder);
                    nettyHandler.handleOrder(NettyCommand.PUSH_EXCHANGE_ORDER_TRADE, sellOrder);
                }
                // 处理K线行情
                if (coinProcessor != null) {
                    coinProcessor.process(trades);
                }
                pushJob.addTrades(symbol, trades);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

19 View Source File : NettyHandler.java
License : MIT License
Project Creator : sengeiou

/**
 * 处理Netty订阅与取消订阅
 */
@HawkBean
public clreplaced NettyHandler {

    @Autowired
    private HawkPushServiceApi hawkPushService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private MessageHandler chatMessageHandler;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private ApnsHandler apnsHandler;

    public void subscribeTopic(Channel channel, String topic) {
        String userKey = channel.id().asLongText();
        NettyCacheUtils.keyChannelCache.put(channel, userKey);
        NettyCacheUtils.storeChannel(topic, channel);
        if (NettyCacheUtils.userKey.containsKey(userKey)) {
            NettyCacheUtils.userKey.get(userKey).add(topic);
        } else {
            Set<String> userkeys = new HashSet<>();
            userkeys.add(topic);
            NettyCacheUtils.userKey.put(userKey, userkeys);
        }
    }

    public void unsubscribeTopic(Channel channel, String topic) {
        String userKey = channel.id().asLongText();
        if (NettyCacheUtils.userKey.containsKey(userKey)) {
            NettyCacheUtils.userKey.get(userKey).remove(topic);
        }
        NettyCacheUtils.keyChannelCache.remove(channel);
    }

    /*@HawkMethod(cmd = NettyCommand.SUBSCRIBE_CHAT,version = NettyCommand.COMMANDS_VERSION)
    public QuoteMessage.SimpleResponse subscribeChat(byte[] body, ChannelHandlerContext ctx){
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("订阅:"+json.toJSONString());
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        String orderId = json.getString("orderId");
        String uid = json.getString("uid");
        if(StringUtils.isEmpty(uid) || StringUtils.isEmpty(orderId)){
            response.setCode(500).setMessage("订阅失败,参数错误");
        }
        else {
            String key = orderId + "-" + uid;
            subscribeTopic(ctx.channel(),key);
            response.setCode(0).setMessage("订阅成功");
        }
        return response.build();
    }*/
    @HawkMethod(cmd = NettyCommand.SUBSCRIBE_GROUP_CHAT)
    public QuoteMessage.SimpleResponse subscribeGroupChat(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("订阅GroupChat:" + json.toJSONString());
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        String uid = json.getString("uid");
        if (StringUtils.isEmpty(uid)) {
            response.setCode(500).setMessage("订阅失败,参数错误");
        } else {
            String key = uid;
            subscribeTopic(ctx.channel(), key);
            response.setCode(0).setMessage("订阅成功");
        }
        return response.build();
    }

    /*@HawkMethod(cmd = NettyCommand.UNSUBSCRIBE_CHAT)
    public QuoteMessage.SimpleResponse unsubscribeChat(byte[] body, ChannelHandlerContext ctx){
        System.out.println(ctx.channel().id());
        JSONObject json = JSON.parseObject(new String(body));
        String orderId = json.getString("orderId");
        String uid = json.getString("uid");
        String key = orderId+"-"+uid;
        unsubscribeTopic(ctx.channel(),key);
        apnsHandler.removeToken(uid);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("取消订阅成功");
        return response.build();
    }*/
    @HawkMethod(cmd = NettyCommand.UNSUBSCRIBE_GROUP_CHAT)
    public QuoteMessage.SimpleResponse unsubscribeGroupChat(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        String uid = json.getString("uid");
        String key = uid;
        unsubscribeTopic(ctx.channel(), key);
        apnsHandler.removeToken(uid);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("取消订阅成功");
        return response.build();
    }

    @HawkMethod(cmd = NettyCommand.SUBSCRIBE_APNS)
    public QuoteMessage.SimpleResponse subscribeApns(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("订阅APNS推送:" + json.toJSONString());
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        String token = json.getString("token");
        String uid = json.getString("uid");
        if (StringUtils.isEmpty(uid) || StringUtils.isEmpty(token)) {
            response.setCode(500).setMessage("订阅失败,参数错误");
        } else {
            apnsHandler.setToken(uid, token);
            response.setCode(0).setMessage("订阅成功");
        }
        return response.build();
    }

    @HawkMethod(cmd = NettyCommand.UNSUBSCRIBE_APNS)
    public QuoteMessage.SimpleResponse unsubscribeApns(byte[] body, ChannelHandlerContext ctx) {
        JSONObject json = JSON.parseObject(new String(body));
        System.out.println("取消订阅APNS推送:" + json.toJSONString());
        String uid = json.getString("uid");
        apnsHandler.removeToken(uid);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("取消订阅成功");
        return response.build();
    }

    @HawkMethod(cmd = NettyCommand.SEND_CHAT)
    public QuoteMessage.SimpleResponse sendMessage(byte[] body, ChannelHandlerContext ctx) {
        System.out.println("发送消息:" + new String(body));
        RealTimeChatMessage message = JSON.parseObject(new String(body), RealTimeChatMessage.clreplaced);
        handleMessage(message);
        QuoteMessage.SimpleResponse.Builder response = QuoteMessage.SimpleResponse.newBuilder();
        response.setCode(0).setMessage("发送成功");
        return response.build();
    }

    /**
     * 推送消息
     * @param key
     * @param result
     */
    public void push(String key, Object result, short command) {
        byte[] body = JSON.toJSONString(result).getBytes();
        Set<Channel> channels = NettyCacheUtils.getChannel(key);
        if (channels != null && channels.size() > 0) {
            System.out.println("下发消息:key=" + key + ",result=" + JSON.toJSONString(result) + ",channel size=" + channels.size());
            hawkPushService.pushMsg(channels, command, body);
        }
    }

    public void handleMessage(RealTimeChatMessage message) {
        if (message.getMessageType() == MessageTypeEnum.NOTICE) {
            Order order = orderService.findOneByOrderId(message.getOrderId());
            ConfirmResult result = new ConfirmResult(message.getContent(), order.getStatus().getOrdinal());
            result.setUidFrom(message.getUidFrom());
            result.setOrderId(message.getOrderId());
            result.setNameFrom(message.getNameFrom());
            // push(message.getOrderId() + "-" + message.getUidTo(),result,NettyCommand.PUSH_CHAT);
            push(message.getUidTo(), result, NettyCommand.PUSH_GROUP_CHAT);
            messagingTemplate.convertAndSendToUser(message.getUidTo(), "/order-notice/" + message.getOrderId(), result);
        } else if (message.getMessageType() == MessageTypeEnum.NORMAL_CHAT) {
            ChatMessageRecord chatMessageRecord = new ChatMessageRecord();
            BeanUtils.copyProperties(message, chatMessageRecord);
            chatMessageRecord.setSendTime(DateUtils.getCurrentDate().getTime());
            chatMessageRecord.setFromAvatar(message.getAvatar());
            // 聊天消息保存到mogondb
            chatMessageHandler.handleMessage(chatMessageRecord);
            chatMessageRecord.setSendTimeStr(DateUtils.getDateStr(chatMessageRecord.getSendTime()));
            // 发送给指定用户(客户端订阅路径:/user/+uid+/+key)
            push(message.getUidTo(), chatMessageRecord, NettyCommand.PUSH_GROUP_CHAT);
            // push(message.getOrderId() + "-" + message.getUidTo(),chatMessageRecord,NettyCommand.PUSH_CHAT);
            apnsHandler.handleMessage(message.getUidTo(), chatMessageRecord);
            messagingTemplate.convertAndSendToUser(message.getUidTo(), "/" + message.getOrderId(), chatMessageRecord);
        }
    }
}

19 View Source File : MachineStatusHandler.java
License : MIT License
Project Creator : qmdx00

/**
 * @author yuanweimin
 * @date 19/06/13 10:54
 * @description 机器设备实时数据的消息处理类
 */
@Slf4j
@Component
public clreplaced MachineStatusHandler implements MessageHandler {

    private final MachineStatusService machineStatusService;

    private final MachineService machineService;

    private final SimpMessagingTemplate template;

    @Autowired
    public MachineStatusHandler(SimpMessagingTemplate template, MachineService machineService, MachineStatusService machineStatusService) {
        this.template = template;
        this.machineService = machineService;
        this.machineStatusService = machineStatusService;
    }

    @Override
    public synchronized void handle(long msgId, String msgBody) {
        // 封装成 Message 实体
        Message msg = MessageUtil.replacedysis(msgId, msgBody);
        // log.info("receive machine status: {}", msg);
        // 映射成 MachineStatus 实体类对象
        MachineStatus status = translate(msg.getDeviceId(), msg.getTimestamp(), msg.getBody());
        // 保存状态数据到数据库中
        machineStatusService.saveStatus(status);
        // 转发到前端 websocket 中
        template.convertAndSend("/topic/msg", status);
    }

    /**
     * 将一条数据流转换成状态数据实体,并生成机器设备信息
     *
     * @param deviceId  设备 ID
     * @param timeStamp 数据上传的时间戳
     * @param body      类型的值
     * @return MachineStatus
     */
    private MachineStatus translate(String deviceId, String timeStamp, String body) {
        // 如果设备信息不存在则根据deviceID创建,需要修改其它描述信息
        Machine machine = machineService.findMachineById(deviceId);
        if (machine == null) {
            machineService.saveMachine(Machine.builder().machineId(deviceId).build());
        }
        // 数据串解析为 Map
        Map<String, String> map = Arrays.stream(body.split("-")).map(et -> et.split("@")).filter(et -> et.length == 2).collect(Collectors.toMap(et -> et[0], et -> et[1]));
        // 构建 MachineStatus 对象
        return MachineStatus.builder().statusId(UUIDUtil.getUUID()).machineId(deviceId).createTime(TimeUtil.toDate(timeStamp)).temperature(map.get("TM")).temperatureWarn(map.get("TR")).fan(map.get("FA")).humidity(map.get("HU")).humidityWarn(map.get("HR")).voltage(map.get("VO")).electric(map.get("CU")).power(map.get("PO")).weight(map.get("WE")).weightWarn(map.get("WR")).motorOpen(map.get("MW")).motorSpeed(map.get("MP")).motorDir(map.get("MI")).slideOpen(map.get("TW")).slideDir(map.get("TD")).slideSpeed(map.get("TS")).rodDistance(map.get("PD")).machineError(map.get("ME")).reservedA(map.get("RA")).reservedB(map.get("RB")).reservedC(map.get("RC")).reservedD(map.get("RD")).build();
    }
}

19 View Source File : ServerController.java
License : Apache License 2.0
Project Creator : pro-cloud

@RestController
@RequestMapping("/serverv")
public clreplaced ServerController {

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @GetMapping
    public Result login() {
        Server server = new Server();
        List<Cpu> cpus = Lists.newArrayList();
        Cpu cpu = new Cpu();
        cpu.setKey("22");
        cpu.setValue("444");
        cpus.add(cpu);
        server.setCpus(cpus);
        simpMessagingTemplate.convertAndSend("/topic/server", JSONUtil.toJsonStr(server));
        return Result.success("22");
    }

    @GetMapping("ai")
    public Result loginv() {
        Server server = new Server();
        List<Cpu> cpus = Lists.newArrayList();
        Cpu cpu = new Cpu();
        cpu.setKey("272");
        cpu.setValue("444");
        cpus.add(cpu);
        server.setCpus(cpus);
        simpMessagingTemplate.convertAndSendToUser("1", "/topic/server", JSONUtil.toJsonStr(server));
        simpMessagingTemplate.convertAndSendToUser("3", "/topic/server", JSONUtil.toJsonStr(server));
        return Result.success("22");
    }

    @GetMapping("aiv")
    public Result loginvai() {
        Server server = new Server();
        List<Cpu> cpus = Lists.newArrayList();
        Cpu cpu = new Cpu();
        cpu.setKey("272");
        cpu.setValue("444");
        cpus.add(cpu);
        server.setCpus(cpus);
        simpMessagingTemplate.convertAndSendToUser("2", "/topic/server", JSONUtil.toJsonStr(server));
        return Result.success("22");
    }
}

19 View Source File : WebSocketController.java
License : MIT License
Project Creator : pram

@Controller
@Slf4j
public clreplaced WebSocketController {

    private final SimpMessagingTemplate template;

    @Autowired
    WebSocketController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @Scheduled(fixedRate = 5000)
    public void sendUpdate() {
        String formattedDate = DateFormat.getTimeInstance().format(new Date());
        log.debug("Sending Update {}", formattedDate);
        this.template.convertAndSend("/topic/update", formattedDate);
    }

    @MessageMapping("/hello")
    public String greeting(String message) throws Exception {
        log.info("Message received {}", message);
        return String.format("Hello %s ", message);
    }
}

19 View Source File : ChatController.java
License : MIT License
Project Creator : PacktPublishing

/**
 * @author Greg Turnquist
 */
// tag::code[]
@Controller
public clreplaced ChatController {

    private final SimpMessagingTemplate template;

    public ChatController(SimpMessagingTemplate template) {
        this.template = template;
    }

    // tag::newChatMessage[]
    @MessageMapping("/chatMessage.new")
    public void newChatMessage(String newChatMessage, Principal principal) {
        if (newChatMessage.startsWith("@")) {
            String user = newChatMessage.substring(0, newChatMessage.indexOf(" "));
            String message = principal.getName() + "(direct): " + newChatMessage;
            // Send message to target user
            template.convertAndSendToUser(user.substring(1), "/queue/chatMessage.new", message);
            // Send copy of message to user who wrote it
            template.convertAndSendToUser(principal.getName(), "/queue/chatMessage.new", message);
        } else {
            String message = principal.getName() + "(channel): " + newChatMessage;
            template.convertAndSend("/topic/chatMessage.new", message);
        }
    }
    // end::newChatMessage[]
}

19 View Source File : GreetingController.java
License : Apache License 2.0
Project Creator : onblog

/**
 * Create by [email protected] 2018/6/19/019 23:49
 */
@Controller
public clreplaced GreetingController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private GcService gcService;

    @Autowired
    private ClreplacedService clreplacedService;

    @Autowired
    private ThreadService threadService;

    @MessageMapping("/gc")
    @SendTo("/topic/gc")
    public List<GcEnreplacedy> socketGc(String name) {
        return gcService.findAllByName(name);
    }

    @MessageMapping("/cl")
    @SendTo("/topic/cl")
    public List<ClreplacedLoadEnreplacedy> socketCl(String name) {
        return clreplacedService.findAllByName(name);
    }

    @MessageMapping("/thread")
    @SendTo("/topic/thread")
    public List<ThreadEnreplacedy> socketThread(String name) {
        return threadService.findAllByName(name);
    }
}

19 View Source File : InfoController.java
License : MIT License
Project Creator : ocinpp

/**
 * Reference: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
 */
@Controller
public clreplaced InfoController {

    @Autowired
    private SimpMessagingTemplate messageTemplate;

    @Scheduled(fixedDelay = 10000)
    public void priceManualConvert() throws Exception {
        double val1 = (new BigDecimal(Math.random() * 1000 + "")).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
        double val2 = (new BigDecimal(Math.random() * 1000 + "")).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
        StockQuote stock1 = new StockQuote("Fantastic Food", val1);
        StockQuote stock2 = new StockQuote("Marvellous Car", val2);
        List<StockQuote> list = new ArrayList<>();
        list.add(stock1);
        list.add(stock2);
        // convert from object to JSON
        ObjectMapper mapper = new ObjectMapper();
        String jsonInString = mapper.writeValuereplacedtring(list);
        this.messageTemplate.convertAndSend("/stock/price", jsonInString);
    }

    @Scheduled(fixedDelay = 5000)
    public void priceAutoConvert() throws Exception {
        double val1 = (new BigDecimal(Math.random() * 1000 + "")).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
        double val2 = (new BigDecimal(Math.random() * 1000 + "")).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
        StockQuote stock1 = new StockQuote("Airplane 1", val1);
        StockQuote stock2 = new StockQuote("Electricity", val2);
        List<StockQuote> list = new ArrayList<>();
        list.add(stock1);
        list.add(stock2);
        // convert from object to JSON
        ObjectMapper mapper = new ObjectMapper();
        String jsonInString = mapper.writeValuereplacedtring(list);
        this.messageTemplate.convertAndSend("/stock/price-fast", jsonInString);
    }
}

19 View Source File : TimeSender.java
License : MIT License
Project Creator : nielsutrecht

@Component
@Slf4j
public clreplaced TimeSender {

    private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss");

    @Autowired
    private SimpMessagingTemplate broker;

    @Autowired
    public TimeSender(final SimpMessagingTemplate broker) {
        this.broker = broker;
    }

    @Scheduled(fixedRate = 5000)
    public void run() {
        String time = LocalTime.now().format(TIME_FORMAT);
        log.info("Time broadcast: {}", time);
        broker.convertAndSend("/topic/greetings", new Greeting("Current time is " + time));
    }
}

19 View Source File : WebSocketController.java
License : Apache License 2.0
Project Creator : mploed

@Controller
public clreplaced WebSocketController {

    private SimpMessagingTemplate template;

    @Autowired
    public WebSocketController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @EventListener
    public void greeting(PartOfScoringPerformed event) throws Exception {
        this.template.convertAndSend("/topic/greetings", new WebSocketMessage(event.getCluster() + " has been scored for Application Number: " + event.getApplicationNumber()));
    }

    @EventListener
    public void greeting(ScoringPerformed event) throws Exception {
        this.template.convertAndSend("/topic/greetings", new WebSocketMessage(event.getApplicationNumber() + " has been scored with " + event.getPoints() + " and final result " + event.getScoreColor()));
    }

    @EventListener
    public void greeting(CreditAgencyResultArrived event) throws Exception {
        this.template.convertAndSend("/topic/greetings", new WebSocketMessage("Credit Agency Result has arrived for Person" + event.getPersonId().toString()));
    }

    @EventListener
    public void greeting(CreditApplicationArrived event) throws Exception {
        this.template.convertAndSend("/topic/greetings", new WebSocketMessage("Credit Application has arrived with ID " + event.getApplicationNumber().toString()));
    }
}

19 View Source File : EventManager.java
License : GNU General Public License v3.0
Project Creator : MoeraOrg

@Service
public clreplaced EventManager {

    private static Logger log = LoggerFactory.getLogger(EventManager.clreplaced);

    private static final String USER_PREFIX = "/user";

    private static final String EVENT_DESTINATION = "/queue";

    private static final String TOKEN_HEADER = "token";

    @Inject
    private Domains domains;

    @Inject
    private SimpMessagingTemplate messagingTemplate;

    @Inject
    private AuthenticationManager authenticationManager;

    private Map<String, EventSubscriber> subscribers = new ConcurrentHashMap<>();

    private List<EventPacket> queue = new ArrayList<>();

    private final long startedAt = Instant.now().getEpochSecond();

    private int lastOrdinal = 0;

    private ReadWriteLock eventsLock = new ReentrantReadWriteLock();

    private final Object deliverySignal = new Object();

    @EventListener(SessionConnectEvent.clreplaced)
    public void sessionConnect(SessionConnectEvent event) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
        if (accessor.getHost() == null) {
            log.debug("Ignoring session {} without a host", accessor.getSessionId());
            return;
        }
        UUID nodeId = domains.getDomainNodeId(accessor.getHost());
        nodeId = nodeId != null ? nodeId : domains.getDomainNodeId(Domains.DEFAULT_DOMAIN);
        boolean admin = false;
        try {
            admin = authenticationManager.isAdminToken(accessor.getFirstNativeHeader(TOKEN_HEADER), nodeId);
        } catch (InvalidTokenException e) {
        // Ignore, the client will detect the problem from REST API requests
        }
        MDC.put("domain", domains.getDomainEffectiveName(accessor.getHost()));
        log.info("Session connect, id = {} {}", accessor.getSessionId(), admin ? "admin" : "non-admin");
        EventSubscriber subscriber = new EventSubscriber();
        subscriber.setNodeId(nodeId);
        subscriber.setSessionId(accessor.getSessionId());
        subscriber.setAdmin(admin);
        subscribers.put(accessor.getSessionId(), subscriber);
    }

    @EventListener(SessionSubscribeEvent.clreplaced)
    public void subscribed(SessionSubscribeEvent event) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
        if (!(USER_PREFIX + EVENT_DESTINATION).equals(accessor.getDestination())) {
            return;
        }
        SeenHeader.Details seen = SeenHeader.parse(accessor);
        initLoggingDomain(accessor.getSessionId());
        log.info("Session subscribed, id = {} seen = {}/{}", accessor.getSessionId(), LogUtil.format(seen.queueStartedAt), LogUtil.format(seen.lastEvent));
        EventSubscriber subscriber = subscribers.get(accessor.getSessionId());
        if (subscriber == null) {
            return;
        }
        if (seen.queueStartedAt == null) {
            subscriber.setLastEventSeen(lastOrdinal);
        } else if (seen.queueStartedAt != startedAt) {
            subscriber.setLastEventSeen(0);
        } else {
            subscriber.setLastEventSeen(seen.lastEvent);
        }
        subscriber.setSubscribed(true);
        Map<String, Object> attributes = accessor.getSessionAttributes();
        String clientIp = (String) attributes.get("ip");
        send(subscriber.getNodeId(), new SubscribedEvent(subscriber.getSessionId(), clientIp));
    }

    @EventListener(SessionUnsubscribeEvent.clreplaced)
    public void unsubscribed(SessionUnsubscribeEvent event) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
        if (!(USER_PREFIX + EVENT_DESTINATION).equals(accessor.getDestination())) {
            return;
        }
        initLoggingDomain(accessor.getSessionId());
        subscribers.remove(accessor.getSessionId());
        log.info("Session unsubscribed, id = {}", accessor.getSessionId());
    }

    @EventListener(SessionDisconnectEvent.clreplaced)
    public void disconnect(SessionDisconnectEvent event) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
        initLoggingDomain(accessor.getSessionId());
        subscribers.remove(accessor.getSessionId());
        log.info("Session disconnected, id = {}", accessor.getSessionId());
    }

    private void initLoggingDomain(String sessionId) {
        EventSubscriber subscriber = subscribers.get(sessionId);
        if (subscriber != null) {
            MDC.put("domain", domains.getDomainName(subscriber.getNodeId()));
        }
    }

    @PostConstruct
    public void init() {
        Thread deliveryThread = new Thread(() -> {
            while (true) {
                try {
                    synchronized (deliverySignal) {
                        deliverySignal.wait();
                    }
                } catch (InterruptedException e) {
                }
                deliver();
            }
        });
        deliveryThread.setName("eventDelivery");
        deliveryThread.setDaemon(true);
        deliveryThread.start();
    }

    private void purge() {
        long boundary = Instant.now().minus(10, ChronoUnit.MINUTES).getEpochSecond();
        queue.removeIf(packet -> packet.getSentAt() < boundary);
    }

    public void send(UUID nodeId, Event event) {
        send(nodeId, null, event);
    }

    public void send(UUID nodeId, String clientId, Event event) {
        MDC.put("domain", domains.getDomainName(nodeId));
        log.info("Event arrived: {}", event.getType());
        eventsLock.writeLock().lock();
        try {
            purge();
            EventPacket packet = new EventPacket();
            packet.setNodeId(nodeId);
            packet.setQueueStartedAt(startedAt);
            packet.setOrdinal(++lastOrdinal);
            packet.setSentAt(Instant.now().getEpochSecond());
            packet.setCid(clientId);
            packet.setEvent(event);
            queue.add(packet);
        } finally {
            eventsLock.writeLock().unlock();
        }
        synchronized (deliverySignal) {
            deliverySignal.notifyAll();
        }
    }

    @Scheduled(fixedDelayString = "PT1M")
    public void everyMinute() {
        retryDelivery();
        pingAll();
    }

    private void retryDelivery() {
        synchronized (deliverySignal) {
            deliverySignal.notifyAll();
        }
    }

    private void pingAll() {
        Set<UUID> nodeIds = subscribers.values().stream().filter(EventSubscriber::isSubscribed).filter(EventSubscriber::isAdmin).map(EventSubscriber::getNodeId).collect(Collectors.toSet());
        nodeIds.forEach(nodeId -> send(nodeId, new PingEvent()));
    }

    private void deliver() {
        log.debug("Delivery of events");
        eventsLock.readLock().lock();
        try {
            if (queue.isEmpty()) {
                return;
            }
            int last = queue.get(0).getOrdinal() + queue.size() - 1;
            subscribers.values().stream().filter(EventSubscriber::isSubscribed).filter(sub -> sub.getLastEventSeen() < last).forEach(this::deliver);
        } finally {
            eventsLock.readLock().unlock();
        }
    }

    private void deliver(EventSubscriber subscriber) {
        initLoggingDomain(subscriber.getSessionId());
        log.debug("Delivering events to {}", subscriber.getSessionId());
        SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
        headerAccessor.setSessionId(subscriber.getSessionId());
        MessageHeaders headers = headerAccessor.getMessageHeaders();
        int first = queue.get(0).getOrdinal();
        int beginIndex = Math.max(0, subscriber.getLastEventSeen() - first + 1);
        try {
            for (int i = beginIndex; i < queue.size(); i++) {
                EventPacket packet = queue.get(i);
                if (!Objects.equals(packet.getNodeId(), subscriber.getNodeId()) || !packet.getEvent().isPermitted(subscriber)) {
                    subscriber.setLastEventSeen(first + i);
                    continue;
                }
                log.debug("Sending event {}: {}", first + i, packet.getEvent().getType());
                messagingTemplate.convertAndSendToUser(subscriber.getSessionId(), EVENT_DESTINATION, packet, headers);
                subscriber.setLastEventSeen(first + i);
            }
        } catch (MessagingException e) {
            log.error("Error sending event", e);
        }
    }
}

19 View Source File : WebsocketDisconnectListener.java
License : GNU General Public License v3.0
Project Creator : MicroIoT

@Component
public clreplaced WebsocketDisconnectListener implements ApplicationListener<SessionDisconnectEvent> {

    private Logger logger = LoggerFactory.getLogger(this.getClreplaced());

    @Autowired
    private DeviceRepository deviceRepository;

    @Autowired
    private AlarmRepository alarmRepository;

    @Autowired
    private SimpMessagingTemplate template;

    @Override
    public void onApplicationEvent(SessionDisconnectEvent event) {
        SessionDisconnectEvent e = (SessionDisconnectEvent) event;
        Date date = new Date(e.getTimestamp());
        if ((Authentication) e.getUser() != null) {
            CustomUserDetails user = (CustomUserDetails) ((Authentication) e.getUser()).getPrincipal();
            if (user.isDevice()) {
                Device device = deviceRepository.findByDeviceAccountUsername(user.getUsername());
                logger.debug("disconnected device is " + user.getUsername() + " at " + date);
                Alarm last = alarmRepository.queryLastAlarm(device.getId());
                if (last == null || (last != null && last.getReportTime().before(date))) {
                    if (device.isConnected()) {
                        device.setConnected(false);
                        deviceRepository.save(device);
                    }
                    Alarm alarm = new Alarm(device, AlarmType.DISCONNECTED_ALARM, null, date);
                    alarm = alarmRepository.save(alarm);
                    String destination = "/topic/alarm." + device.getId();
                    template.convertAndSend(destination, alarm);
                }
            }
        }
    }
}

19 View Source File : WebsocketConnectedListener.java
License : GNU General Public License v3.0
Project Creator : MicroIoT

@Component
public clreplaced WebsocketConnectedListener implements ApplicationListener<SessionConnectedEvent> {

    private Logger logger = LoggerFactory.getLogger(this.getClreplaced());

    @Autowired
    private DeviceRepository deviceRepository;

    @Autowired
    private AlarmRepository alarmRepository;

    @Autowired
    private SimpMessagingTemplate template;

    @Override
    public void onApplicationEvent(SessionConnectedEvent event) {
        SessionConnectedEvent e = (SessionConnectedEvent) event;
        Date date = new Date(e.getTimestamp());
        if ((Authentication) e.getUser() != null) {
            CustomUserDetails user = (CustomUserDetails) ((Authentication) e.getUser()).getPrincipal();
            if (user.isDevice()) {
                Device device = deviceRepository.findByDeviceAccountUsername(user.getUsername());
                logger.debug("connected device is " + user.getUsername() + " at " + date);
                Alarm last = alarmRepository.queryLastAlarm(device.getId());
                if (last == null || (last != null && last.getReportTime().before(date))) {
                    if (!device.isConnected()) {
                        device.setConnected(true);
                        deviceRepository.save(device);
                    }
                    Alarm alarm = new Alarm(device, AlarmType.CONNECTED_ALARM, null, date);
                    alarm = alarmRepository.save(alarm);
                    String destination = "/topic/alarm." + device.getId();
                    template.convertAndSend(destination, alarm);
                }
            }
        }
    }
}

19 View Source File : AlarmService.java
License : GNU General Public License v3.0
Project Creator : MicroIoT

@Service
public clreplaced AlarmService extends IoTService {

    @Autowired
    private AlarmRepository alarmRepository;

    @Autowired
    private DeviceRepository deviceRepository;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private SimpMessagingTemplate template;

    @Transactional
    public Alarm report(AlarmInfo info) {
        Device device = getCurrentDevice();
        return reportAlarm(info, device);
    }

    @Transactional
    public Alarm report(SubDeviceAlarmInfo info) {
        Device subDevice = deviceRepository.findById(info.getDeviceId()).get();
        if (deviceService.isChild(subDevice.getId()))
            return reportAlarm(info, subDevice);
        else
            throw new StatusException("device id error");
    }

    private Alarm reportAlarm(AlarmInfo info, Device device) {
        if (device.getDeviceType().getAlarmTypes() == null || !device.getDeviceType().getAlarmTypes().containsKey(info.getAlarmType()))
            throw new NotFoundException("alarm type: " + info.getAlarmType() + " in this device: " + device.getName());
        AttributeType alarmType = device.getDeviceType().getAlarmTypes().get(info.getAlarmType());
        DataValue value = DataValue.getDataValue(info.getAlarmInfo(), alarmType.getDataType());
        Alarm alarm = new Alarm(device, info.getAlarmType(), value, info.getReportTime());
        alarm = alarmRepository.save(alarm);
        String destination = Topic.TOPIC_ALARM + device.getId();
        template.convertAndSend(destination, alarm);
        return alarm;
    }

    public Alarm listAlarm(String id) {
        return alarmRepository.findById(id).get();
    }

    public Page<Alarm> listAll() {
        Pageable pageable = getPageable(null);
        return alarmRepository.findAll(pageable);
    }

    public Page<Alarm> listAlarms(AlarmPageInfo info) {
        Pageable pageable = getPageable(info);
        Domain domain = getCurrentDomain();
        return alarmRepository.queryAlarm(domain.getId(), info.getNotifyObjectId(), info.getAlarmType(), info.getReportFrom(), info.getReportTo(), info.getReceiveFrom(), info.getReceiveTo(), pageable);
    }
}

19 View Source File : EventSender.java
License : GNU Affero General Public License v3.0
Project Creator : MatagTheGame

/**
 * Sends events to the browser.
 */
@Component
@AllArgsConstructor
public clreplaced EventSender {

    private static final Logger LOGGER = LoggerFactory.getLogger(EventSender.clreplaced);

    private final SimpMessagingTemplate webSocketTemplate;

    private final ObjectMapper objectMapper;

    public void sendToUser(String sessionId, String username, Event event) {
        var eventString = serializeToString(event);
        if (!event.getType().equals("HEALTHCHECK")) {
            if (username != null) {
                LOGGER.info("Sending event to {} - {}: {}", sessionId, username, eventString);
            } else {
                LOGGER.info("Sending event to {}: {}", sessionId, eventString);
            }
        }
        webSocketTemplate.convertAndSendToUser(sessionId, "/events", eventString);
    }

    public void sendToUser(String sessionId, Event event) {
        sendToUser(sessionId, null, event);
    }

    public void sendToPlayer(Player player, Event event) {
        sendToUser(player.getToken().getSessionId(), player.getName(), event);
    }

    public void sendToPlayers(List<Player> players, Event event) {
        players.forEach(player -> sendToPlayer(player, event));
    }

    private String serializeToString(Object event) {
        try {
            return objectMapper.writeValuereplacedtring(event);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

19 View Source File : NotificationSimpAspect.java
License : GNU General Public License v3.0
Project Creator : marcinadd

@Aspect
@Component
public clreplaced NotificationSimpAspect {

    private final SimpMessagingTemplate messagingTemplate;

    private final NotificationService notificationService;

    public NotificationSimpAspect(SimpMessagingTemplate messagingTemplate, NotificationService notificationService) {
        this.messagingTemplate = messagingTemplate;
        this.notificationService = notificationService;
    }

    @AfterReturning(value = "execution (* com.projecty.projectyweb.notifications.NotificationService.createNotificationAndSave(..))", returning = "notification")
    public void sendSimpNotificationToSpecificUser(Notification notification) {
        notification.setStringValue(notificationService.buildNotificationString(notification));
        messagingTemplate.convertAndSendToUser(notification.getUser().getUsername(), "/secured/user/queue/specific-user", notification);
    }
}

See More Examples