精华内容
下载资源
问答
  • 查询数据库数据,查询出一条给前端推送一条,表里新增一条数据告诉前端新进来一条数据了,并把数据推送给前端。
  • 1、引入依赖: compile "org.springframework.boot:spring-boot-starter-web:${...compile "org.springframework.boot:spring-boot-starter-websocket:${verSpringBoot}" 2、添加Webscoket配置: /**...

    1、引入依赖:

    compile "org.springframework.boot:spring-boot-starter-web:${verSpringBoot}"
    compile "org.springframework.boot:spring-boot-starter-websocket:${verSpringBoot}"
        
    

    2、添加Webscoket配置:

     /**
         * ServerEndpointExporter 作用
         *
         * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
         *
         * @return
         */
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    

    3、后端代码:

    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.io.IOException;
    import java.util.concurrent.ConcurrentHashMap;
    
    @Component
    @ServerEndpoint("/websocket/{id}")
    public class WebSocketServer {
    
    
        public Logger log = LoggerFactory.getLogger(getClass());
        
        /**
         * 客户端ID
         */
        private String id = "";
    
        /**
         * 与某个客户端的连接会话,需要通过它来给客户端发送数据
         */
        private Session session;
    
        /**
         * 记录当前在线连接数(为保证线程安全,须对使用此变量的方法加lock或synchronized)
         */
        private static int onlineCount = 0;
    
        /**
         * 用来存储当前在线的客户端(此map线程安全)
         */
        private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
    
        /**
         * 连接建立成功后调用
         */
        @OnOpen
        public void onOpen(@PathParam(value = "id") String id, Session session) {
            this.session = session;
            // 接收到发送消息的客户端编号
            this.id = id;
            // 加入map中
            webSocketMap.put(id, this);
            // 在线数加1
            addOnlineCount();
            log.info("客户端" + id + "加入,当前在线数为:" + getOnlineCount());
            try {
                sendMessage("WebSocket连接成功");
            } catch (IOException e) {
                log.error("WebSocket IO异常");
            }
        }
    
        /**
         * 连接关闭时调用
         */
        @OnClose
        public void onClose() {
            // 从map中删除
            webSocketMap.remove(this.id);
            // 在线数减1
            subOnlineCount();
            log.info("有一连接关闭,当前在线数为:" + getOnlineCount());
        }
    
        /**
         * 收到客户端消息后调用
         * @param message 客户端发送过来的消息<br/>
         *                消息格式:内容 - 表示群发,内容|X - 表示发给id为X的客户端
         * @param session 用户信息
         */
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("来自客户端的消息:" + message);
            String[] messages = message.split("[|]");
            try {
                if (messages.length > 1) {
                    sendToUser(messages[0], messages[1]);
                } else {
                    sendToAll(messages[0]);
                }
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
    
        /**
         * 发生错误时回调
         *
         * @param session 用户信息
         * @param error 错误
         */
        @OnError
        public void onError(Session session, Throwable error) {
            log.error("WebSocket发生错误");
            error.printStackTrace();
        }
    
        /**
         * 推送信息给指定ID客户端,如客户端不在线,则返回不在线信息给自己
         *
         * @param message 客户端发来的消息
         * @param sendClientId 客户端ID
         */
        public void sendToUser(String message, String sendClientId) throws IOException {
            if (webSocketMap.get(sendClientId) != null) {
                if (!id.equals(sendClientId)) {
                    webSocketMap.get(sendClientId)
                        .sendMessage("客户端" + id + "发来消息:" + " <br/> " + message);
                } else {
                    webSocketMap.get(sendClientId).sendMessage(message);
                }
            } else {
                // 如客户端不在线,则返回不在线信息给自己
                sendToUser("当前客户端不在线", id);
            }
        }
        
        public static void sendToWeb(String message, String sendClientId) throws IOException {
            if (webSocketMap.get(sendClientId) != null) {
               webSocketMap.get(sendClientId).sendMessage(message);
            } else {
                // 如客户端不在线,则返回不在线信息给自己
                System.out.println(sendClientId + "=当前客户端不在线");
            }
        }
    
        /**
         * 群送发送信息给所有人
         *
         * @param message 要发送的消息
         */
        public void sendToAll(String message) throws IOException {
            for (String key : webSocketMap.keySet()) {
                webSocketMap.get(key).sendMessage(message);
            }
        }
    
        /**
         * 发送消息
         * @param message 要发送的消息
         */
        private void sendMessage(String message) throws IOException {
            this.session.getBasicRemote().sendText(message);
        }
    
        /**
         * 获取在线人数
         * @return 在线人数
         */
        private static synchronized int getOnlineCount() {
            return onlineCount;
        }
    
        /**
         * 有人上线时在线人数加一
         */
        private static synchronized void addOnlineCount() {
            WebSocketServer.onlineCount++;
        }
    
        /**
         * 有人下线时在线人数减一
         */
        private static synchronized void subOnlineCount() {
            WebSocketServer.onlineCount--;
        }
    
    }
    

    4、前端代码:

    <!DOCTYPE HTML>
    <html>
    <head>
    <title>My WebSocket</title>
    </head>
    
    <body>
        <input id="text" type="text" />
        <button onclick="send()">Send</button>
        <button onclick="closeWebSocket()">Close</button>
        <div id="message"></div>
    </body>
    
    <script type="text/javascript">
        var websocket = null;
    
        //判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址
        if ('WebSocket' in window) {
            websocket = new WebSocket("ws://127.0.0.1:16666/ts/websocket/1");
        } else {
            alert('Not support websocket')
        }
    
        //连接发生错误的回调方法
        websocket.onerror = function() {
            setMessageInnerHTML("error");
        };
    
        //连接成功建立的回调方法
        websocket.onopen = function(event) {
            setMessageInnerHTML("open");
        }
    
        //接收到消息的回调方法
        websocket.onmessage = function(event) {
            setMessageInnerHTML(event.data);
        }
    
        //连接关闭的回调方法
        websocket.onclose = function() {
            setMessageInnerHTML("close");
        }
    
        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function() {
            websocket.close();
        }
    
        //将消息显示在网页上
        function setMessageInnerHTML(innerHTML) {
            document.getElementById('message').innerHTML += innerHTML + '<br/>';
        }
    
        //关闭连接
        function closeWebSocket() {
            websocket.close();
        }
    
        //发送消息
        function send() {
            var message = document.getElementById('text').value;
            websocket.send(message);
        }
    </script>
    </html>
    

    5、测试代码:

    @RequestMapping(value="/sendMessage/{clientId}",method = {RequestMethod.GET})
        public void sendTest(@PathVariable String clientId) throws Throwable{
            WebSocketServer.sendToWeb("你有一个新任务"+System.currentTimeMillis(), clientId);
        }
    
    展开全文
  • python打包exe可执行文件_后端开发python打包exe可执行文件的方法:1、执行【pip install PyInstaller】...php如何实现websocket首先在php代码中创建socket服务并监听端口信息;python如何生成随机密码_后端开发py...

    python打包exe可执行文件_后端开发

    python打包exe可执行文件的方法:1、执行【pip install PyInstaller】命令安装PyInstaller;2、进入python文件所在路径,执行【pyinstaller -F Test.py】命令进行打包。

    59cef86db77b79bf1fedd245557ccd0b.png

    php如何实现websocket

    首先在php代码中创建socket服务并监听端口信息;

    python如何生成随机密码_后端开发

    python生成随机密码的方法:1、首先引进string库和random库;2、然后通过string.ascii_letters和string.ascii_digits引进大小写字母和数字;3、最后使用sample()函数返回随机元素即可。

    //传相应的IP与端口进行创建socket操作

    function WebSocket($address,$port){

    $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

    socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);//1表示接受所有的数据包

    socket_bind($server, $address, $port);

    socket_listen($server);

    return $server;

    }

    然后设计一个循环挂起websocket通道,进行数据的接收、处理和发送;

    //对创建的socket循环进行监听,处理数据

    function run(){

    //死循环,直到socket断开

    while(true){

    $changes=$this->sockets;

    $write=NULL;

    $except=NULL;

    /*

    //这个函数是同时接受多个连接的关键,我的理解它是为了阻塞程序继续往下执行。

    socket_select ($sockets, $write = NULL, $except = NULL, NULL);

    $sockets可以理解为一个数组,这个数组中存放的是文件描述符。当它有变化(就是有新消息到或者有客户端连接/断开)时,socket_select函数才会返回,继续往下执行。

    $write是监听是否有客户端写数据,传入NULL是不关心是否有写变化。

    $except是$sockets里面要被排除的元素,传入NULL是”监听”全部。

    最后一个参数是超时时间

    如果为0:则立即结束

    如果为n>1: 则最多在n秒后结束,如遇某一个连接有新动态,则提前返回

    如果为null:如遇某一个连接有新动态,则返回

    */

    socket_select($changes,$write,$except,NULL);

    foreach($changes as $sock){

    //如果有新的client连接进来,则

    if($sock==$this->master){

    //接受一个socket连接

    $client=socket_accept($this->master);

    //给新连接进来的socket一个唯一的ID

    $key=uniqid();

    $this->sockets[]=$client; //将新连接进来的socket存进连接池

    $this->users[$key]=array(

    'socket'=>$client, //记录新连接进来client的socket信息

    'shou'=>false //标志该socket资源没有完成握手

    );

    //否则1.为client断开socket连接,2.client发送信息

    }else{

    $len=0;

    $buffer='';

    //读取该socket的信息,注意:第二个参数是引用传参即接收数据,第三个参数是接收数据的长度

    do{

    $l=socket_recv($sock,$buf,1000,0);

    $len+=$l;

    $buffer.=$buf;

    }while($l==1000);

    //根据socket在user池里面查找相应的$k,即健ID

    $k=$this->search($sock);

    //如果接收的信息长度小于7,则该client的socket为断开连接

    if($len<7){

    //给该client的socket进行断开操作,并在$this->sockets和$this->users里面进行删除

    $this->send2($k);

    continue;

    }

    //判断该socket是否已经握手

    if(!$this->users[$k]['shou']){

    //如果没有握手,则进行握手处理

    $this->woshou($k,$buffer);

    }else{

    //走到这里就是该client发送信息了,对接受到的信息进行uncode处理

    $buffer = $this->uncode($buffer,$k);

    if($buffer==false){

    continue;

    }

    //如果不为空,则进行消息推送操作

    $this->send($k,$buffer);

    }

    }

    }

    }

    }

    最后等待客户端进行连接即可。

    var ws = new WebSocket("ws://IP:端口");

    //握手监听函数

    ws.onopen=function(){

    //状态为1证明握手成功,然后把client自定义的名字发送过去

    if(so.readyState==1){

    //握手成功后对服务器发送信息

    so.send('type=add&ming='+n);

    }

    }

    //错误返回信息函数

    ws.onerror = function(){

    console.log("error");

    };

    //监听服务器端推送的消息

    ws.onmessage = function (msg){

    console.log(msg);

    }

    //断开WebSocket连接

    ws.onclose = function(){

    ws = false;

    }

    推荐教程:《PHP教程》《PHP7》

    展开全文
  • 1.前端调用WebSocket server代码: //调用WebSocket server batchSeting() { this.openStatue = 1; const serve = window.location.hostname; this.websock = new WebSocket(`ws://${serve}:8088/e...

    1.前端调用WebSocket server代码:

        //调用WebSocket server
    	batchSeting() {
    	      this.openStatue = 1;
    	      const serve = window.location.hostname;
    	      this.websock = new WebSocket(`ws://${serve}:8088/examService`);
    	      this.websock.onmessage = this.websocketonmessage;
    	      this.websock.onerror = this.websocketonerror;
    	      this.websock.onopen = this.websocketonopen;
    	      this.websock.onclose = this.websocketclose;
    	    },
    	    websocketonopen() { // 连接建立之后执行send方法发送数据
    	      const data = {
    	        pointCode: this.pointCodes.join(','),
    	        key: this.openStatue // 0 关 1 开
    	      };
    	      console.log(data);
    	      this.websocketsend(JSON.stringify(data));
    	    },
    	    websocketonerror() {
    	      console.log('WebSocket连接失败');
    	    },
    	    // 数据接收
    	    websocketonmessage(e) { 
    	      const data = e.data.length > 0 ? JSON.parse(e.data) : {};
    	      this.remindTime = data.remindTime;
    	      this.completeNum = data.completeNum;
    	      this.pointExam(data.pointCode);
    	      if (this.completeNum === this.pointCodes.length) { /** 已经完成体检 */
    	        this.dialogVisible = false;
    	        this.websock.close();// 关闭websocket
    	      }
    	    }
    

    2.后端 netty服务类

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.handler.codec.http.HttpObjectAggregator;
    import io.netty.handler.codec.http.HttpServerCodec;
    import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
    import io.netty.handler.stream.ChunkedWriteHandler;
    @Component
    public class ExamTCPServer {
    
    	//@Value(value="${NETTY_PORT}")
    	private static int port = 8088;
    	
    	private static final Logger logger = LoggerFactory.getLogger(ExamTCPServer.class);
    	
    	private static int maxFrameLength = 1024 * 10;
    	
    	public void run() throws Exception {
    		NioEventLoopGroup bossLoopGroup = new NioEventLoopGroup(1);
    		//默认核心个数的2倍
    		NioEventLoopGroup workLoopGroup = new NioEventLoopGroup();
    		
    		try {
    			ServerBootstrap serverBootstrap = new ServerBootstrap()
    				.group(bossLoopGroup, workLoopGroup)
    				.channel(NioServerSocketChannel.class)
    				.childOption(ChannelOption.TCP_NODELAY, true)
    				.option(ChannelOption.SO_BACKLOG, 16)
    				.childOption(ChannelOption.SO_KEEPALIVE, true)
    				.childHandler(new ChannelInitializer<SocketChannel>() {
    						@Override
    						protected void initChannel(SocketChannel ch) throws Exception {
    							ChannelPipeline pipeline = ch.pipeline();
    							//基于http协议,使用http的编码和解码器
    		                    pipeline.addLast(new HttpServerCodec());
    		                    pipeline.addLast(new ChunkedWriteHandler());
    		                    pipeline.addLast(new HttpObjectAggregator(7168));
    		                    /*
    		                     * 将 http协议升级为 ws协议 
    		                     */
    		                    pipeline.addLast(new WebSocketServerProtocolHandler("/examService"));
    		                    pipeline.addLast(new TCPServerHandler());
    						}
    					});
    				
    			ChannelFuture future = serverBootstrap.bind(port).sync();
    			
    			future.channel().closeFuture().sync();
    		} finally {
    			bossLoopGroup.shutdownGracefully();
    			workLoopGroup.shutdownGracefully();
    		}
    		
    	}
    	
    }
    

    3.tcp服务启动类:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.stereotype.Component;
    
      @Component
    public class StartEvent implements ApplicationListener<ContextRefreshedEvent>{
    
    	private static final Logger logger = LoggerFactory.getLogger(StartEvent.class);
    	
    	@Override
    	public void onApplicationEvent(ContextRefreshedEvent event) {
    		if (event.getApplicationContext().getParent() == null) {
    			logger.info("启动业务程序!");
    
    			// 启动tcp 服务
    			new Thread(new Runnable() {
    				@Override
    				public void run() {
    					try {
    						new ExamTCPServer().run();
    					} catch (Exception e) {
    						logger.error("启动失败");
    					}
    				}
    			}).start();
    		}
    	}
    }
    

    4.后端消息推送:

    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;
    
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelId;
    import io.netty.channel.group.ChannelGroup;
    import io.netty.channel.group.DefaultChannelGroup;
    import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
    import io.netty.util.concurrent.GlobalEventExecutor;
    
    public class ChannelSupervise {
    
        private   static ChannelGroup GlobalGroup=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
        private  static ConcurrentMap<String, ChannelId> ChannelMap=new ConcurrentHashMap();
        public  static void addChannel(Channel channel){
            GlobalGroup.add(channel);
            ChannelMap.put(channel.id().asShortText(),channel.id());
        }
        public static void removeChannel(Channel channel){
            GlobalGroup.remove(channel);
            ChannelMap.remove(channel.id().asShortText());
        }
        public static  Channel findChannel(String id){
            return GlobalGroup.find(ChannelMap.get(id));
        }
        public static void send2All(TextWebSocketFrame tws){
            GlobalGroup.writeAndFlush(tws);
        }
    	
    }
    

    5.业务处理:

    import java.io.UnsupportedEncodingException;
    import java.text.DecimalFormat;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.stream.Collectors;
    
    import javax.annotation.PostConstruct;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class TCPServerHandler extends ChannelInboundHandlerAdapter{
    
    /**
     * channelAdded
     * channelRegistered
     * channelActive
     * channelRead
     * channelInactive
     * channelUnregistered
     */
    
    private static Logger LOGGER = LoggerFactory.getLogger(TCPServerHandler.class);
    
    private DateTimeFormatter formatter;
    private List<OperationPersonnelVO> operationList;
    @Autowired
    private OperationPersonnelDao operationPersonnelDao;
    //初始化业务处理数据
    @PostConstruct
    private void initPerson(){
       //...省略
    }
    
      	// -- 连接通道上下文信息
        public static Map<String, SocketMessageVO> channelMap = new ConcurrentHashMap();
    
    	private ExamCheckService examCheckService;
    	private NotifyService notifyService;
    	
    /**
     * 连接建立
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception{
    	notifyService = (NotifyService)SpringContextUtil.getBean("notifyServiceImpl");
    	examCheckService = (ExamCheckService)SpringContextUtil.getBean("examCheckService");
    	
    	SocketMessageVO messageVO = new SocketMessageVO();
    	String userId = SessionInfoUtil.getSessionUserId().toString();
    	messageVO.setCtx(ctx);
    	messageVO.setUserId(userId);
    	channelMap.put(userId, messageVO);
    	
    	String info = String.format("站点:%s  接入连接", getRemoteAddress(ctx));
    	LOGGER.info(info);
    	ChannelSupervise.addChannel(ctx.channel());
    }
    
    /**
     * 连接断开
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception{
    	for (Map.Entry<String,SocketMessageVO> map : channelMap.entrySet()) {
    		if (map.getValue().getCtx() == ctx) {
    			channelMap.remove(map.getKey());
    		}
    	}
    	String info = String.format("站点:%s  连接断开", getRemoteAddress(ctx));
    	LOGGER.info(info);
    	ChannelSupervise.removeChannel(ctx.channel());
    }
    
    /**
     * 新消息自动调用
     * @throws UnsupportedEncodingException 
     * @throws InterruptedException 
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException, InterruptedException{
    	String json = ((TextWebSocketFrame)msg).text();
    	//数据转换
    	//SocketMessageVO messageVO = JsonUtil.json2Object(json, SocketMessageVO.class);
    	if(messageVO.getKey() == 0){
    	   //取消业务处理
    	   //。。。
    	}else{
    	   //业务处理
    		//。。。
    	}
    }
    
    /**
     * 异常处理回调
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    	cause.printStackTrace();
    	String error = String.format("用户:%s 连接异常 【%s】", getRemoteAddress(ctx), cause.getMessage());
    	LOGGER.error(error);
    	ctx.close();
    }
    
    /**
     * 通过上下文获取channelid
     */
    public static String getRemoteAddress(ChannelHandlerContext ctx){
    	return ctx.channel().remoteAddress().toString();
    }
    

    6.通道上下文信息:

    import io.netty.channel.ChannelHandlerContext;
    public class SocketMessageVO {
    		public SocketMessageVO(){
    			super();
    		}
    	
    public SocketMessageVO(String userId, String pointCode, String remindTime, Integer completeNum) {
    	super();
    	this.userId = userId;
    	this.pointCode = pointCode;
    	this.remindTime = remindTime;
    	this.completeNum = completeNum;
    }
    /**
     * 消息id
     */
    private String id;
    /**
     * 聊天消息
     */
    private String message;
    /**
     * 用户id
     */
    private String userId;
    
    private String pointCode;
    
    /**
     * 单站点进度
     */
    private Double progress = 0d;
    /**
     * 剩余时间
     */
    private String remindTime;
    /**
     * 已体检完成站点的个数
     */
    private Integer completeNum;
    /**
     * 通道上下文
     */
    private ChannelHandlerContext ctx;
    
    /**
     * 0关闭 1开启
     */
    private Integer key;
    
    public String getUserId() {
    	return userId;
    }
    public void setUserId(String userId) {
    	this.userId = userId;
    }
    public String getId() {
    	return id;
    }
    public void setId(String id) {
    	this.id = id;
    }
    public String getMessage() {
    	return message;
    }
    public void setMessage(String message) {
    	this.message = message;
    }
    public String getPointCode() {
    	return pointCode;
    }
    public void setPointCode(String pointCode) {
    	this.pointCode = pointCode;
    }
    public Double getProgress() {
    	return progress;
    }
    public void setProgress(Double progress) {
    	this.progress = progress;
    }
    public String getRemindTime() {
    	return remindTime;
    }
    public void setRemindTime(String remindTime) {
    	this.remindTime = remindTime;
    }
    public ChannelHandlerContext getCtx() {
    	return ctx;
    }
    public void setCtx(ChannelHandlerContext ctx) {
    	this.ctx = ctx;
    }
    public Integer getCompleteNum() {
    	return completeNum;
    }
    public void setCompleteNum(Integer completeNum) {
    	this.completeNum = completeNum;
    }
    
    public Integer getKey() {
    	return key;
    }
    
    public void setKey(Integer key) {
    	this.key = key;
    }}
    

    7.实现的效果:
    在这里插入图片描述

    展开全文
  • SpringBoot整合WebSocket实现后端向前端主动推送消息

    一、引入websocket依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>

    二、WebSocket配置

    @Configuration
    public class WebSocketConfig {
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }

    三、 WebSocket服务(前端连接地址ws://ip:端口/websocket,请自行替换ip、端口和接口名称)

    @ServerEndpoint(value = "/websocket")
    @Component
    public class WebSocketServer {
        private final static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    
        //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
        private static int onlineCount = 0;
        //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
        private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
    
        //与某个客户端的连接会话,需要通过它来给客户端发送数据
        private Session session;
    
        /**
         * 连接建立成功调用的方法
         */
        @OnOpen
        public void onOpen(Session session) {
            this.session = session;
            //加入set中
            webSocketSet.add(this);
            //在线数加1
            addOnlineCount();
            log.info("有新连接加入!当前在线人数为" + getOnlineCount());
            try {
                sendMessage("连接成功");
            } catch (IOException e) {
                log.error("websocket IO异常");
            }
        }
    
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose() {
            //从set中删除
            webSocketSet.remove(this);
            //在线数减1
            subOnlineCount();
            log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
        }
    
        /**
         * 收到客户端消息后调用的方法
         *
         * @param message 客户端发送过来的消息
         */
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("来自客户端的消息:" + message);
    
            //群发消息
            for (WebSocketServer item : webSocketSet) {
                try {
                    item.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
            log.error("发生错误");
            error.printStackTrace();
        }
    
        public void sendMessage(String message) throws IOException {
            this.session.getBasicRemote().sendText(message);
        }
    
        /**
         * 群发自定义消息
         */
        public static void sendInfo(String message) throws IOException {
            log.info(message);
            for (WebSocketServer item : webSocketSet) {
                try {
                    item.sendMessage(message);
                } catch (IOException e) {
                    continue;
                }
            }
        }
    
        public static synchronized int getOnlineCount() {
            return onlineCount;
        }
    
        public static synchronized void addOnlineCount() {
            WebSocketServer.onlineCount++;
        }
    
        public static synchronized void subOnlineCount() {
            WebSocketServer.onlineCount--;
        }
    }

    四、消息推送

    后端调用WebServer的sendInfo接口(例如:WebSocketServer.sendInfo("Hello World");)实现主动向前端推送消息

    展开全文
  • 具体步骤: https://www.cnblogs.com/bianzy/p/5822426.html 解决Springboot使用WebSocket是无法通过@Autowired注入bean问题 https://blog.csdn.net/qq_28289867/article/details/80423042
  • Java后端WebSocket的Tomcat实现的简要说明,可以参考一下
  • 一、后端 1.pom文件引入依赖 <!-- webSocket--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> &...
  • 最近有个需求是后端主动推送消息给前端,通过一番艰难险阻总算是给完成了,选择使用的是websocket,可以前后端进行通信 1、框架: 后端:springboot2.x 前端:vue2.x 2、原理: 后端建立一个websocket服务器,提供一...
  • vue项目集成websocket以及后端spring boot的实现创建后端spring boot工程创建vue的前端工程 创建后端spring boot工程 打开我们的IDEA创建一个空的工程,空的工程名字叫vue-websocket-spring-boot-demo,接着在该空的...
  • websocket Java后端案例

    2015-06-25 15:26:07
    websocket相关资源,及时推送,tomcat7实现
  • 于是有了这一篇,本文主要演示的是WebSocket的API使用,如果要实现服务端主动推送实时数据的功能,需要进行重新设计和编码实现,保证推送的唯一可达性和具备容错机制。 本文在“Moshow郑锴”大佬的教程上,进行了...
  • Springboot Vue WebSocket实现后端服务推送通知功能一、业务场景二、实现过程1. Springboot pom.xml引入WebSocket依赖jar包2. 编写WebSocketConfig配置类3. 编写WebSocketServer服务实现类 一、业务场景 最近在做一...
  • 一、搭建一个简单的springBoot项目,导入以下jar包 javax javaee-api 7.0 provided org.springframework.boot spring-boot-starter-websocket org.springframework.boot spring-boot-starter-tomcat 二,编写...
  • 主要为大家详细介绍了SpringMVC整合websocket实现消息推送及触发功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • webSocket心跳检测机制及代码思想 次文章只是提供一下本人设计思路 心跳检测有很多方式可以实现在此 只是为大家提供一下思路大家一起相互学习 一起进步
  • 一、web端数据实时刷新方案?... ②优化选项: 心跳检测及自动重连机制,当网络断开或者后端服务问题造成客户端 websocket 断开,程序会自动尝试重新连接直到再次连接成功 ③用到的函数: onopen:连接成功 oner
  • WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safrie,Firefox,Opera,IE等等 vue案例: <template> <div> <table> <thead> <tr> <...
  • 目前情况是这样,我调用A的接口...但这个数据是变动的,所以想做成推送的形式,了解到Spring可以实现Websocket。但是具体怎么实现不太清楚。有大佬可以给说下怎么实现吗?最好能有各demo我研究下[face]qq:83.gif[/face]
  • 核心配置:WebSocketServer 因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller @ ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的...
  • 在工作遇到一个功能开发,应用场景是:后端(springboot项目)通过消息队列机制接收事件,并通过websocket实时推向前端(vue项目),从而实现前后端数据实时推送。 接下来介绍一下如何在前后端代码中实现websocket...
  • packagecom.yjlc.platform.utils.webSocket;importcom.alibaba.fastjson.JSON;importcom.yjlc.platform.User;import javax.websocket.*;importjavax.websocket.server.PathParam;importjavax.websocket.server.Serve...
  • 第一:引入jar由于项目是springboot的项目所以我这边简单的应用了springboot自带的socket jarorg.springframework.bootspring-boot-starter-websocket第二:Socket代码编写import org.springframework.context....
  • Spring 4.0的一个最大更新是增加了websocket的支持。websocket提供了一个在web应用中的高效、双向的通讯,需要考虑到客户端(浏览器...以一个简单的网页聊天为应用场景,在Java EE环境下,其实现方式大抵有以下几种...
  • https://blog.svenhetin.com/chu-tan-he-shi-xian-websocketxin-tiao-zhong-lian/https://www.crifan.com/websocket_ping_pong_best_interval_time/https://www.oschina.net/question/137225_27929心跳重连缘由...
  • websocket看文章必读vue部分实现前端的websocket 看文章必读 这个文章所涉及的技术并不是很理解,但是主要是实现一个前后端实现通信的功能! vue部分实现前端的websocket 首先要通过 new WebSocket(“服务器地址”...
  • 心跳重连缘由在使用websocket过程中,可能会出现网络断开的情况,比如信号不好...如果当前发送websocket数据到后端,一旦请求超时,onclose便会执行,这时候便可进行绑定好的重连操作。因此websocket心跳重连就应运...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,628
精华内容 7,451
关键字:

websocket后端实现