websocket按组织机构推送消息

WebsocketServer:
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yangfeng
 **/
@ServerEndpoint("/websocket/{orgCode}")
@Component
public class WebsocketServer {

    private static Logger LOG = LoggerFactory.getLogger(WebsocketServer.class);

    /**
     * 存放所有在线的客户端
     */
    private static Map<String, List<Session>> clients = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(@PathParam(value = "orgCode") String orgCode, Session session) {
        LOG.info("{}机构,新的客户端连接了: {}", orgCode, session.getId());
        List<Session> sessions = clients.get(orgCode);
        if (sessions == null) {
            sessions = new ArrayList<>();
        }
        sessions.add(session);
        clients.put(orgCode, sessions);
    }

    /**
     * 客户端关闭
     *
     * @param session session
     */
    @OnClose
    public void onClose(@PathParam(value = "orgCode") String orgCode, Session session) {
        LOG.info("{}机构,用户断开了, id为:{}", orgCode, session.getId());
        List<Session> sessions = clients.get(orgCode);
        if (!CollectionUtils.isEmpty(sessions)) {
            Iterator<Session> sessionIt = sessions.iterator();
            while (sessionIt.hasNext()) {
                Session s = sessionIt.next();
                if (s.getId().equalsIgnoreCase(session.getId())) {
                    //将掉线的用户移除在线的组里
                    sessionIt.remove();
                }
            }
        }
    }

    /**
     * 发生错误
     *
     * @param throwable e
     */
    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }

    /**
     * 收到客户端发来消息
     *
     * @param message 消息对象
     */
    @OnMessage
    public void onMessage(@PathParam(value = "orgCode") String orgCode, String message) {
        LOG.info("{}机构,服务端收到客户端发来的消息: {}", orgCode, message);
        this.sendAll(orgCode, message);
    }

    /**
     * 群发消息
     *
     * @param message 消息内容
     */
    private void sendAll(String orgCode, String message) {
        List<Session> sessions = clients.get(orgCode);
        if (!CollectionUtils.isEmpty(sessions)) {
            sessions.stream().forEach(o -> o.getAsyncRemote().sendText(message));
        }
    }
}

vue:

websocket:

<template lang="html">
  <header class="header fBox">
    <BreadBar/>
    <div class="fBoxJe">
      <el-dropdown @command="handleCommand">
        <span class="el-dropdown-link">
          <el-button type="warning" icon="el-icon-user-solid" circle size="mini"></el-button> &nbsp;{{userName}}&nbsp;<i
          class="el-icon-arrow-down el-icon--right"></i>
        </span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="updatePassword" icon="el-icon-key">修改密码</el-dropdown-item>
          <el-dropdown-item command="signOut" icon="el-icon-switch-button">退出登录</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>

      <template v-if="formVisible">
        <div class="customClass">
          <el-dialog title="修改密码" :visible.sync="formVisible" width="30%">
            <el-form :model="form" :rules="rules" ref="form" class="form-class form-input">
              <el-form-item label="账户:" label-width="110px">
                <el-input v-model="form.userName" disabled="disabled" autocomplete="off"></el-input>
              </el-form-item>
              <el-form-item label="原密码:" label-width="110px" required>
                <el-input type="password" v-model="form.originPassword" autocomplete="off"></el-input>
              </el-form-item>
              <el-form-item label="新密码:" label-width="110px" required prop="newPassword">
                <el-input type="password" v-model="form.newPassword" autocomplete="off"></el-input>
              </el-form-item>
              <el-form-item label="确认密码:" label-width="110px" required>
                <el-input type="password" v-model="form.conformPassword" autocomplete="off"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button size="mini" @click="formVisible = false">取消</el-button>
              <el-button size="mini" type="primary" @click="submit" :loading="editLoading">确定</el-button>
            </div>
          </el-dialog>
        </div>
      </template>

    </div>
  </header>
</template>

<script>
  import {mapActions, mapState} from 'vuex'
  import BreadBar from './BreadBar'

  export default {
    name: 'headerBar',
    components: {BreadBar},
    data () {
      return {
        websock: null,
        wsUrl: null,
        timer: null,
        form: {
          userName: '',
          originPassword: '',
          newPassword: '',
          conformPassword: ''
        },
        formVisible: false,
        rules:
          {
            newPassword: [
              {required: true, message: '请输入新密码'},
              {pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/, message: '密码为长度6-20的字母和数字组成', trigger: 'blur'}
            ]
          }
      }
    },

    created () {
      this.initWebSocket()
    },

    destroyed () {
      this.websock.close() //离开路由之后断开websocket连接
      clearInterval(this.timer)
    },

    computed: {
      ...mapState('login', [
        'user'
      ]),

      userName: function () {
        let user = JSON.parse(this.user)
        if (user) {
          return user.trueName ? user.trueName : user.userName
        }
      },

      ...mapState('user', [
        'editLoading',
      ]),
    },
    methods: {
      initWebSocket () { //初始化
        let user = JSON.parse(localStorage.getItem('user'))
        if (user) {
          this.wsUrl = 'ws://192.168.1.121:8080/websocket/' + user.agencyCode
        } else {
          console.log('用户未登录')
          return
        }
        this.websock = new WebSocket(this.wsUrl)
        this.websock.onmessage = this.onmessage
        this.websock.onopen = this.onopen
        this.websock.onerror = this.onerror
        this.websock.onclose = this.onclose
      },

      onopen () { //连接建立之后执行send方法发送数据
        console.log('socket连接成功')
        // 添加心跳检测,每30秒发一次数据,防止连接断开(这跟服务器的设置有关,如果服务器没有设置每隔多长时间不发消息断开,可以不进行心跳设置)
        let self = this
        this.timer = setInterval(() => {
          try {
            self.websock.send('heart check')
          } catch (err) {
            console.log('断开了:' + err)
            //self.initWebSocket()
          }
        }, 30000)
      },

      onmessage (ev) {
        if (ev && ev.data && ev.data != 'heart check') {
          this.$notify({
            title: '系统通知',
            dangerouslyUseHTMLString: true,
            message: ev.data,
            position: 'bottom-right',
            duration: 60000,
            type: 'warning'
          })
        }
        console.log(ev, '连接正常')
      },

      onerror () {
        console.log('websocket服务出错了---onerror')
        this.initWebSocket() // 连接失败后尝试重新连接
      },

      onclose () {
        console.log('websocket服务关闭了+++onclose')
      },

      ...mapActions('login', [
        'logout'
      ]),

      ...mapActions('user', [
        'updatePwd'
      ]),

      handleCommand (command) {
        if (command == 'signOut') {
          this.signOut()
        } else if (command == 'updatePassword') {
          this.formVisible = true
          let user = JSON.parse(this.user)
          this.form.userName = user.userName
          this.form.originPassword = ''
          this.form.newPassword = ''
          this.form.conformPassword = ''
        }
      },

      //修改密码
      submit () {
        this.$refs['form'].validate((valid) => {
          if (valid) {
            if (this.form.newPassword != this.form.conformPassword) {
              this.$notify.error({
                title: '提示',
                message: '新密码和确认密码输入不一致'
              })
              return
            }
            let data = new FormData()
            data.append('userName', this.form.userName)
            data.append('originPassword', this.form.originPassword)
            data.append('newPassword', this.form.newPassword)
            this.updatePwd(data).then(() => {
              this.$notify.success({
                title: '提示',
                message: '操作成功'
              })
              this.formVisible = false
            })
          }
        })
      },

      signOut () {
        this.$confirm('确定退出登录?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          callback: action => {
            if (action == 'confirm') {
              this.logout()
                .then(res => {
                  localStorage.clear()
                  this.$router.replace({name: 'Login'})
                })
            }
          }
        })
      }
    }
  }
</script>

<style lang="less">
  .header {
    width: 100%;
    height: 3.17rem;
    min-height: 3.17rem;
    color: #8492A6;
    background: #fff;
    padding: 0 2.17rem 0 0.8rem;
    box-sizing: border-box;
    border-bottom: 1px solid #E7EBEF;

    .userName {
      margin-left: 5px;
      font-size: 1.17rem;
    }

    .el-dropdown-link {
      cursor: pointer;
    }

    .el-icon-arrow-down {
      font-size: 12px;
    }

    .icon {
      width: 1.33rem;
      margin-left: 1.67rem;

      &.logout {
        cursor: pointer;

        &:hover {
          opacity: .6;
        }
      }
    }
  }
</style>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值