设为首页 加入收藏

TOP

再谈 websocket 论架构设计(二)
2018-02-22 14:32:40 】 浏览:1498
Tags:再谈 websocket 架构 设计
进行交互,前端可以使用stomp.js类库进行交互,消息一STOMP协议格式进行传输,这样就规定了消息传输格式。
消息进入后端以后,可以将消息与实现STOMP格式的代理器进行整合。
这是为了消息统一管理,进行机器扩容时,可进行负载均衡部署
  • 使用spring websocket:
    使用spring websocket,是因为他提供了STOMP的传输自协议的同时,还提供了StockJS的支持。
    当然,除此之外,spring websocket还提供了权限整合的功能,还有自带天生与spring家族等相关框架进行无缝整合。
  • 应用场景

    应用背景

    2016年,在公司与同事一起讨论和开发了公司内部的客服系统,由于前端技能的不足,很多通讯方面的问题,无法亲自调试前端来解决问题。

    因为公司技术架构体系以前后端分离为主,故前端无法协助后端调试,后端无法协助前端调试

    在加上websocket为公司刚启用的协议,了解的人不多,导致前后端调试问题重重。

    一年后的今天,我打算将前端重温,自己来调试一下前后端,来发掘一下之前联调的问题.

    当然,前端,我只是考虑stomp.js和sockt.js的使用。

    代码阶段设计

    角色

    1. 客服
    2. 客户

    登录用户状态

    1. 上线
    2. 下线

    分配策略

    1. 用户登陆后,应该根据用户角色进行分配

    关系保存策略

    1. 应该提供关系型保存策略: 考虑内存式策略(可用于测试),redis式策略
      备注:优先应该考虑实现Inmemory策略,用于测试,让关系保存策略与存储平台无关

    通讯层设计

    1. 归类topic的广播设计(通讯方式:1-n)
    2. 归类queue的单点设计(通讯方式:1-1)

    代码实现

    角色

    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.User;
    import java.util.Collection;
    public enum Role {
      CUSTOMER_SERVICE,
      CUSTOMER;
    
    
      public static boolean isCustomer(User user) {
          Collection<GrantedAuthority> authorities = user.getAuthorities();
          SimpleGrantedAuthority customerGrantedAuthority = new SimpleGrantedAuthority("ROLE_" + Role.CUSTOMER.name());
          return authorities.contains(customerGrantedAuthority);
      }
    
      public static boolean isCustomerService(User user) {
          Collection<GrantedAuthority> authorities = user.getAuthorities();
          SimpleGrantedAuthority customerServiceGrantedAuthority = new SimpleGrantedAuthority("ROLE_" + Role.CUSTOMER_SERVICE.name());
          return authorities.contains(customerServiceGrantedAuthority);
      }
    }

    代码中User对象,为安全对象,即 spring中org.springframework.security.core.userdetails.User,为UserDetails的实现类。
    User对象中,保存了用户授权后的很多基础权限信息,和用户信息。
    如下:

    public interface UserDetails extends Serializable {
      Collection<? extends GrantedAuthority> getAuthorities();
    
      String getPassword();
    
      String getUsername();
    
      boolean isAccountNonExpired();
    
      boolean isAccountNonLocked();
    
      boolean isCredentialsNonExpired();
    
      boolean isEnabled();
    }

    方法 #isCustomer 和 #isCustomerService 用来判断用户当前是否是顾客或者是客服。

    登录用户状态

    public interface StatesManager {
    
        enum StatesManagerEnum{
            ON_LINE,
            OFF_LINE
        }
    
        void changeState(User user , StatesManagerEnum statesManagerEnum);
    
        StatesManagerEnum currentState(User user);
    
    }

    设计登录状态时,应存在登录状态管理相关的状态管理器,此管理器只负责更改用户状态和获取用户状态相关操作。
    并不涉及其他关联逻辑,这样的代码划分,更有助于面向接口编程的扩展性

    分配策略

    public interface DistributionUsers {
      void distribution(User user);
    }

    分配角色接口设计,只关注传入的用户,并不关注此用户是客服或者用户,具体需要如何去做,由具体的分配策略来决定。

    关系保存策略

    public interface RelationHandler {
    
      void saveRelation(User customerService,User customer);
    
      List<User> listCustomers(User customerService);
    
      void deleteRelation(User customerService,User customer);
    
      void saveCustomerService(User customerService);
    
      List<User> listCustomerService();
    
      User getCustomerService(User customer);
    
      boolean exist(User user);
    
      User availableNextCustomerService();
    
    }

    关系保存策略,亦是只关注关系保存相关,并不在乎于保存到哪个存储介质中。
    实现类由Inmemory还是redis还是mysql,它并不专注。
    但是,此处需要注意,对于这种关系保存策略,开发测试时,并不涉及高可用,可将Inmemory先做出来用于测试。
    开发功能同时,相关同事再来开发其他介质存储的策

    首页 上一页 1 2 3 4 5 6 下一页 尾页 2/6/6
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇运用组合模式实现复合搜索条件构建 下一篇通向架构师的道路(第十三天)Axi..

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目