app互斥登录,只能登录一个.

思路:

1.手机app的每一次请求都携带参数(每个手机的唯一设备号),放在请求头中.当app登录成功之后,获取参数存到数据库中.

2.添加拦截器,获取请求头里面的唯一设备号,如果和当前登陆者数据库里面的一致,则通过,否则返回false,提示设备已经登录.

拦截器配置:

<mvc:interceptors>
    <!-- 放sql注入攻击防御 -->
    <mvc:interceptor>
        <!-- 需拦截的地址 -->
        <mvc:mapping path="/**" />
        <!-- 需排除拦截的地址 -->
        <mvc:exclude-mapping path="/resources/**" />
        <mvc:exclude-mapping path="/api/auth/cas-app/login" />
        <mvc:exclude-mapping path="/auth/cas-app/login" />
        <bean class="com.boeryun.interceptor.AppMutexInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

拦截器:

public class AppMutexInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        if(("android".equals(Global.getRequest().getHeader("DEVICE-USER-AGENT")) || "ios".equals(Global.getRequest().getHeader("DEVICE-USER-AGENT")))){
            String  deviceNumber  =  Global.getRequest().getHeader("deviceNumber");
            String sql = MessageFormat.format(" select deviceModel from {0} where uuid =''{1}'' ",
                    DbHelper.getTableName("base_staff"),Global.getUserId());
            if(DbHelper.getScalar(sql)!=null && DbHelper.getScalar(sql).toString().equals(deviceNumber) ){
                return true;
            }else{
//                response.setHeader("Content-Type", "text/html;charset=UTF-8");
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                JSONObject map = new JSONObject();
                map.put("Status", "502");
                map.put("Message","您的账号在另外一台设备登录!");
                response.getWriter().append(map.toString());
                return false;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

 

在 macOS 上,可以使用 `QSystemSemaphore` 和 `QSharedMemory` 实现互斥,确保只启动一个程序实例。具体做法是在程序启动时创建一个命名的 `QSystemSemaphore`,并尝试获得它的锁。如果锁已经被其他程序持有,则代表已有实例在运行,此时可以将新的参数传递给已有的实例,并退出当前实例。如果锁没有被持有,则代表没有实例在运行,此时可以正常启动程序。 以下是一个示例代码: ```cpp #include <QApplication> #include <QSystemSemaphore> #include <QSharedMemory> #include <QDebug> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建一个命名的 QSystemSemaphore QSystemSemaphore semaphore("myApp", 1); // 尝试获得锁 if (!semaphore.tryAcquire()) { // 如果锁已经被其他程序持有,则将新的参数传递给已有的实例 QSharedMemory sharedMemory("myApp"); if (!sharedMemory.create(sizeof(int))) { sharedMemory.attach(); } int *params = static_cast<int*>(sharedMemory.data()); *params = 123; sharedMemory.unlock(); return 0; } // 如果锁没有被持有,则正常启动程序 MyMainWindow mainWindow; mainWindow.show(); return app.exec(); } ``` 在上面的代码中,我们首先创建一个命名的 `QSystemSemaphore`,然后尝试获得它的锁。如果锁已经被其他程序持有,则代表已有实例在运行,此时我们创建一个命名的 `QSharedMemory`,将新的参数写入共享内存中,并释放锁,然后退出当前实例。 如果锁没有被持有,则代表没有实例在运行,此时我们正常启动程序,创建主窗口并显示出来。 需要注意的是,如果程序异常退出,锁可能会被一直持有,导致无法启动新的实例。因此,需要在程序退出时释放锁。可以在主窗口的 `closeEvent()` 中释放锁,或者使用 `QCoreApplication::aboutToQuit()` 信号释放锁。 ```cpp void MyMainWindow::closeEvent(QCloseEvent *event) { // 释放锁 QSystemSemaphore semaphore("myApp", 1); semaphore.release(); QMainWindow::closeEvent(event); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值