电脑登录微信,手机退出微信,电脑端微信仍然在线(IOS)

多微信情况下,手机端登录微信,通过扫码登录电脑端微信后,切换手机微信,电脑端微信自动推出。如何让手机用微信A,电脑端用微信B。

一、扫码登录电脑微信

二、IOS手机打开飞行模式

三、在飞行模式下,退出微信
需要等待大概30秒,就会退出

四、退出登录后,联网直接登录另外账户即可

阿里云消息队列 RocketMQ 5.x版- springboot JAVA客户端接入方式

主要是公司为了高可用方案 使用的是阿里云的RocketMQ 5.x版

公司用的spring cloud alibaba 那一套 架构

不过阿里云的mq不会自动创建 topic和group 需要在控制台手动创建 不然会报错

下面配置中的实例账户密码需要在这里查看


首先在项目中引入

 <rocketmq-version>2.3.0</rocketmq-version>
 
 <!-- rocketmq-spring-boot-starter -->
            <dependency>
                <groupId>org.apache.rocketmq</groupId>
                <artifactId>rocketmq-spring-boot-starter</artifactId>
                <version>${rocketmq-version}</version>
                <exclusions>
                    <exclusion>
                        <artifactId>fastjson</artifactId>
                        <groupId>com.alibaba</groupId>
                    </exclusion>
                    <exclusion>
                        <artifactId>slf4j-api</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>

nacos配置:

rocketmq:
#如果使用当前Demo访问阿里云RocketMQ 4.0系列实例,接入点应该是类似这样的格式  http://MQ_INST_XXX:xxx,注意!!!一定要有http协议头
#如果使用当前Demo访问阿里云RocketMQ 5.0系列实例,接入点应该是类似这样的格式  rmq-cn-xxx.xx:xxx,注意!!!一定不要自己添加http协议头
  name-server: z9x07.cn-hangzhou.rmq.aliyuncs.com:8080
  consumer:
   #如果使用阿里云RocketMQ 5.0系列实例,请设置实例详情页获取的实例用户名,不要设置阿里云账号的AccessKeyId。
   access-key: L6JJ6Yy2xxx
   #如果使用阿里云RocketMQ 5.0系列实例,请设置实例详情页获取的实例密码,不要设置阿里云账号的AccessKeySecret。
   secret-key: 582F4nF1xx
   # 注意,4.0实例需要在控制台实例详情中查看是否有命名空间,无命名空间则不需要填写此项
   instance-name: rmq-cn-x0r37
  producer:
   #如果使用阿里云RocketMQ 5.0系列实例,请设置实例详情页获取的实例用户名,不要设置阿里云账号的AccessKeyId。
   access-key: L6JJ6Yy2xxx
   #如果使用阿里云RocketMQ 5.0系列实例,请设置实例详情页获取的实例密码,不要设置阿里云账号的AccessKeySecret。
   secret-key: 582F4nF1xx
   group: lili_group
   send-message-timeout: 30000

消费端:

package com.honghan.im.listener;

import cn.hutool.json.JSONUtil;
import com.honghan.im.config.GoodsTagsEnum;
import com.honghan.im.domain.FootPrint;
import com.honghan.im.service.impl.BusinessServiceImpl;
import com.honghan.im.service.FootprintService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 商品消息
 *
 * @author LinXin
 * @since 2024/6/2114:46
 **/
@Component
@Slf4j
@RocketMQMessageListener(topic = "${lili.data.rocketmq.goods-topic}", consumerGroup = "${lili.data.rocketmq.goods-group}")
public class GoodsMessageListener implements RocketMQListener<MessageExt> {

    private static final int BATCH_SIZE = 10;


    /**
     * 用户足迹
     */
    @Autowired
    private FootprintService footprintService;
    @Autowired
    private BusinessServiceImpl businessService;

    @Override
  //  @RetryOperation
    public void onMessage(MessageExt messageExt) {

        switch (GoodsTagsEnum.valueOf(messageExt.getTags())) {
            //查看商品
            case VIEW_GOODS:
                FootPrint footPrint = JSONUtil.toBean(new String(messageExt.getBody()), FootPrint.class);
                footprintService.saveFootprint(footPrint);
                break;   //商品评价
            case GOODS_COMMENT_COMPLETE:
                businessService.updateGoodsCommentNum(new String(messageExt.getBody()));
                break;
            default:
                log.error("商品执行异常:{}", new String(messageExt.getBody()));
                break;
        }
    }
}

生产端:

package com.honghan.im.dubbo;

import com.honghan.common.core.config.RocketmqCustomProperties;
import com.honghan.im.api.RemoteIMRocketMQService;
import com.honghan.im.config.GoodsTagsEnum;
import com.honghan.common.core.config.RocketmqSendCallbackBuilder;
import com.honghan.im.domain.FootPrint;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
@DubboService
@Slf4j
public class RemoteIMRocketMQServiceImpl implements RemoteIMRocketMQService {
    /**
     * rocketMq
     */
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    /**
     * rocketMq配置
     */
    @Autowired
    private RocketmqCustomProperties rocketmqCustomProperties;

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void asyncSend(Long userId, Long shopId, Long goodsId, String skuId) {
        FootPrint footPrint = new FootPrint(userId+"", shopId+"", goodsId+"", skuId+"");
        String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.VIEW_GOODS.name();
        rocketMQTemplate.asyncSend(destination, footPrint, RocketmqSendCallbackBuilder.commonCallback());
    }

    @Override
    public void publishEvent(String text) {
        String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GOODS_COMMENT_COMPLETE.name();
        //发送订单变更mq消息
        rocketMQTemplate.asyncSend(destination, text, RocketmqSendCallbackBuilder.commonCallback());

        //rocketMQTemplate.asyncSend( rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.GOODS_COMMENT_COMPLETE.name(), text)));

//        applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("同步商品评价消息",
//            rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.GOODS_COMMENT_COMPLETE.name(),
//            text));
    }
}

java 工程模式实现快递查询

1.先写一个接口类
2.写个实现接口的类
3.在写一个工程类在里面判断类型返回不同的实现类

package cn.lili.modules.logistics;

import cn.lili.modules.logistics.entity.dto.LabelOrderDTO;
import cn.lili.modules.logistics.entity.enums.LogisticsEnum;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.modules.system.entity.vo.Traces;

import java.util.Map;

/**
 * 物流插件接口
 *
 * @author Bulbasaur
 * @author Bulbasaur
 * @since 2023-02-16
 */
public interface LogisticsPlugin {


    /**
     * 插件名称
     */
    LogisticsEnum pluginName();

    /**
     * 实时查询快递
     *
     * @param logistics 物流公司
     * @param expNo
     * @param phone
     * @return 物流信息
     */
    Traces pollQuery(Logistics logistics, String expNo, String phone);

    /**
     * 实时查询地图轨迹
     *
     * @param logistics 物流公司
     * @param expNo     单号
     * @param phone     收件人手机号
     * @param from      出发地信息,最小颗粒到市级,例如:广东省深圳市
     * @param to        目的地信息,最小颗粒到市级,例如:广东省深圳市
     * @return 物流信息
     */
    Traces pollMapTrack(Logistics logistics, String expNo, String phone, String from, String to);

    /**
     * 电子面单打印
     *
     * @param labelOrderDTO 电子面单DTO
     * @return
     */
    Map labelOrder(LabelOrderDTO labelOrderDTO);

    String createOrder(OrderDetailVO orderDetailVO);

}
package cn.lili.modules.logistics;

import cn.hutool.json.JSONUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.logistics.entity.enums.LogisticsEnum;
import cn.lili.modules.logistics.plugin.kdniao.KdniaoPlugin;
import cn.lili.modules.logistics.plugin.kuaidi100.Kuaidi100Plugin;
import cn.lili.modules.logistics.plugin.shunfeng.ShunfengPlugin;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.LogisticsSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 文件服务抽象工厂 直接返回操作类
 *
 * @author Bulbasaur
 * @version v1.0
 * 2022-06-06 11:35
 */

@Component
public class LogisticsPluginFactory {


    @Autowired
    private SettingService settingService;


    /**
     * 获取logistics client
     *
     * @return
     */
    public LogisticsPlugin filePlugin() {

        LogisticsSetting logisticsSetting = null;
        try {
            Setting setting = settingService.get(SettingEnum.LOGISTICS_SETTING.name());
            logisticsSetting = JSONUtil.toBean(setting.getSettingValue(), LogisticsSetting.class);
            switch (LogisticsEnum.valueOf(logisticsSetting.getType())) {
                case KDNIAO:
                    return new KdniaoPlugin(logisticsSetting);
                case KUAIDI100:
                    return new Kuaidi100Plugin(logisticsSetting);
                case SHUNFENG:
                    return new ShunfengPlugin(logisticsSetting);
                default:
                    throw new ServiceException();
            }
        } catch (Exception e) {
            throw new ServiceException();
        }
    }


}
package cn.lili.modules.logistics.plugin.kuaidi100;

import cn.lili.modules.logistics.LogisticsPlugin;
import cn.lili.modules.logistics.entity.dto.LabelOrderDTO;
import cn.lili.modules.logistics.entity.enums.LogisticsEnum;
import cn.lili.modules.logistics.plugin.kuaidi100.utils.Kuaidi100SignUtils;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.store.entity.dos.StoreLogistics;
import cn.lili.modules.store.entity.dto.StoreDeliverGoodsAddressDTO;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.modules.system.entity.dto.LogisticsSetting;
import cn.lili.modules.system.entity.vo.Traces;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.LabelV2;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.api.QueryTrackMap;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.contant.PrintType;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.ManInfo;
import com.kuaidi100.sdk.request.PrintReq;
import com.kuaidi100.sdk.request.QueryTrackParam;
import com.kuaidi100.sdk.request.QueryTrackReq;
import com.kuaidi100.sdk.request.labelV2.OrderReq;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.kuaidi100.sdk.response.QueryTrackMapResp;
import com.kuaidi100.sdk.response.QueryTrackResp;
import com.kuaidi100.sdk.response.samecity.OrderResp;
import com.kuaidi100.sdk.utils.SignUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 快递100插件
 *
 * @author Bulbasaur
 */
@Slf4j
public class Kuaidi100Plugin implements LogisticsPlugin {


    @Autowired
    private LogisticsSetting logisticsSetting;

    public Kuaidi100Plugin(LogisticsSetting logisticsSetting) {
        this.logisticsSetting = logisticsSetting;
    }

    @Override
    public LogisticsEnum pluginName() {
        return LogisticsEnum.KUAIDI100;
    }

    @Override
    public Traces pollQuery(Logistics logistics, String expNo, String phone) {
        try {
            QueryTrackReq queryTrackReq = new QueryTrackReq();
            QueryTrackParam queryTrackParam = new QueryTrackParam();
            queryTrackParam.setCom(logistics.getCode());
            queryTrackParam.setNum(expNo);
            queryTrackParam.setPhone(phone);
            String param = new Gson().toJson(queryTrackParam);

            queryTrackReq.setParam(param);
            queryTrackReq.setCustomer(logisticsSetting.getKuaidi100Customer());
            queryTrackReq.setSign(Kuaidi100SignUtils.querySign(param, logisticsSetting.getKuaidi100Key(), logisticsSetting.getKuaidi100Customer()));

            IBaseClient baseClient = new QueryTrack();
            HttpResult httpResult = baseClient.execute(queryTrackReq);
            QueryTrackResp queryTrackResp = new Gson().fromJson(httpResult.getBody(), QueryTrackResp.class);
            log.info(String.valueOf(queryTrackResp.getData()));

            List<Map> traces = new ArrayList<>();
            for (QueryTrackData queryTrackData : queryTrackResp.getData()) {
                Map map = new HashMap<String, String>();
                map.put("AcceptTime", queryTrackData.getTime());
                map.put("AcceptStation", queryTrackData.getContext());
                map.put("Remark", null);
                traces.add(map);
            }
            return new Traces(logistics.getName(), expNo, traces);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Traces pollMapTrack(Logistics logistics, String expNo, String phone, String from, String to) {
        try {
            QueryTrackReq queryTrackReq = new QueryTrackReq();
            QueryTrackParam queryTrackParam = new QueryTrackParam();
            queryTrackParam.setCom(logistics.getCode());
            queryTrackParam.setNum(expNo);
            queryTrackParam.setPhone(phone);
            queryTrackParam.setFrom(from);
            queryTrackParam.setTo(to);
            queryTrackParam.setResultv2("5");
            String param = new Gson().toJson(queryTrackParam);

            queryTrackReq.setParam(param);
            queryTrackReq.setCustomer(logisticsSetting.getKuaidi100Customer());
            queryTrackReq.setSign(SignUtils.querySign(param, logisticsSetting.getKuaidi100Key(), logisticsSetting.getKuaidi100Customer()));

            IBaseClient baseClient = new QueryTrackMap();
            HttpResult result = baseClient.execute(queryTrackReq);

            QueryTrackMapResp queryTrackMapResp = new Gson().fromJson(result.getBody(), QueryTrackMapResp.class);
            System.out.println(queryTrackMapResp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Map<String, Object> labelOrder(LabelOrderDTO labelOrderDTO) {
        try {
            //订单
            Order order = labelOrderDTO.getOrder();
            //订单货物
            List<OrderItem> orderItems = labelOrderDTO.getOrderItems();
            //获取对应物流
            Logistics logistics = labelOrderDTO.getLogistics();
            //收件人地址
            String[] consigneeAddress = order.getConsigneeAddressPath().split(",");
            //获取店家信息
            StoreDeliverGoodsAddressDTO storeDeliverGoodsAddressDTO = labelOrderDTO.getStoreDeliverGoodsAddressDTO();
            //发件人地址
            String[] consignorAddress = storeDeliverGoodsAddressDTO.getSalesConsignorAddressPath().split(",");
            //店铺-物流公司设置
            StoreLogistics storeLogistics = labelOrderDTO.getStoreLogistics();


            ManInfo recManInfo = new ManInfo();
            recManInfo.setName(order.getConsigneeName());
            recManInfo.setMobile(order.getConsigneeMobile());
            recManInfo.setPrintAddr(consigneeAddress[0] + consigneeAddress[1] + consigneeAddress[2] + consigneeAddress[3] + order.getConsigneeDetail());

            ManInfo sendManInfo = new ManInfo();
            sendManInfo.setName(storeDeliverGoodsAddressDTO.getSalesConsignorName());
            sendManInfo.setMobile(storeDeliverGoodsAddressDTO.getSalesConsignorMobile());
            sendManInfo.setPrintAddr(consignorAddress[0] + consignorAddress[1] + consignorAddress[2] + consignorAddress[3] + storeDeliverGoodsAddressDTO.getSalesConsignorDetail());

            OrderReq orderReq = new OrderReq();
            orderReq.setKuaidicom(logistics.getCode());
            orderReq.setCount(1);
            // orderReq.setSiid(siid);
            //orderReq.setTempId("60f6c17c7c223700131d8bc3");
            orderReq.setSendMan(sendManInfo);
            orderReq.setRecMan(recManInfo);

            orderReq.setPrintType(PrintType.CLOUD);

            String param = new Gson().toJson(orderReq);
            String t = System.currentTimeMillis() + "";

            PrintReq printReq = new PrintReq();
            printReq.setT(t);
            printReq.setKey(logisticsSetting.getKuaidi100Key());
            printReq.setSign(SignUtils.printSign(param, t, logisticsSetting.getKuaidi100Key(), logisticsSetting.getKuaidi100Customer()));
            printReq.setMethod(ApiInfoConstant.ORDER);
            printReq.setParam(param);

            IBaseClient baseClient = new LabelV2();
            HttpResult result = baseClient.execute(printReq);
            System.out.println(result.getBody());
            QueryTrackMapResp queryTrackMapResp = new Gson().fromJson(result.getBody(), QueryTrackMapResp.class);
            OrderResp orderResp = new Gson().fromJson(result.getBody(), OrderResp.class);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String createOrder(OrderDetailVO orderDetailVO) {
        return null;
    }


}

org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, TopicTest异常解决

可能性1:
可能是由于mq没启动成功
进入对应bin目录,修改文件runserver.sh runbroker.sh。 把VM参数都改成

-Xms256m -Xmx256m -Xmn128m 

或者你想要的大小。默认给的8G,如果不改,很可能启动不成功。

4、启动 NameServer。

nohup sh bin/mqnamesrv & .

查看是否启动成功

jps

查看启动日志

tail -f ~/logs/rocketmqlogs/namesrv.log

5、启动 BrokerServer。

nohup sh bin/mqbroker -n localhost:9876 & .

查看启动日志

tail -f ~/logs/rocketmqlogs/broker.log

6、关闭服务。

sh bin/mqshutdown broker
sh bin/mqshutdown namesrv

可能性2:

Broker 禁止自动创建Topic,且用户没有通过手动创建此Topic,或者broker 和 Nameserver网络不通

二、解决方案:

  1. 修改broker.properties配置,自动创建topic,添加如下:

    autoCreateTopicEnable=true

    官方文档中启动 Broker是这样的:

    nohup sh bin/mqbroker -n localhost:9876 &

    其实我们可以改成这样:

    nohup sh bin/mqbroker -n localhost:9876 autoCreateTopicEnable=true & 

nginx 反代ws协议进行im在线聊天的 websocket协议

   location /im-api/ {
        proxy_redirect off;
        proxy_pass http://172.26.71.51:9218/;      # 转发
        proxy_set_header Host $host;
        proxy_set_header X-Real_IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
        proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;   # 升级协议头 websocket
        proxy_set_header Connection upgrade;
            proxy_set_header Connection $connection_upgrade;
          }