天天看點

springmvc+maven+netty-socketio服務端建構實時通信

1.maven引入依賴jar包

 <dependency>

          <groupId>com.corundumstudio.socketio</groupId>

          <artifactId>netty-socketio</artifactId>

          <version>1.7.7</version>

</dependency>

socketio服務端:SocketIo_Server.java

import java.util.Map;

import com.corundumstudio.socketio.AckRequest;

import com.corundumstudio.socketio.Configuration;

import com.corundumstudio.socketio.SocketIOClient;

import com.corundumstudio.socketio.SocketIOServer;

import com.corundumstudio.socketio.listener.ConnectListener;

import com.corundumstudio.socketio.listener.DataListener;

import com.corundumstudio.socketio.listener.DisconnectListener;

public class SocketIo_Server {

    public static void main(String[] args) throws InterruptedException {

        Configuration config = new Configuration();

        //伺服器主機ip,這裡配置本機

        config.setHostname("localhost");

        //端口,任意

        config.setPort(9092);

        config.setMaxFramePayloadLength(1024 * 1024);

        config.setMaxHttpContentLength(1024 * 1024);

        SocketIOServer server = new SocketIOServer(config);

        //監聽廣告推送事件,advert_info為事件名稱,自定義

        server.addEventListener("advert_info", String.class, new DataListener<String>(){

            @Override

            public void onData(SocketIOClient client, String data, AckRequest ackRequest) throws ClassNotFoundException {

                //用戶端推送advert_info事件時,onData接受資料,這裡是string類型的json資料,還可以為Byte[],object其他類型

                String sa = client.getRemoteAddress().toString();

                String clientIp = sa.substring(1,sa.indexOf(":"));//擷取用戶端連接配接的ip

                Map params = client.getHandshakeData().getUrlParams();//擷取用戶端url參數

                System.out.println(clientIp+":用戶端:************"+data);

            }

        });

        //監聽通知事件

        server.addEventListener("notice_info", String.class, new DataListener<String>() {

            @Override    

            public void onData(SocketIOClient client, String data, AckRequest ackRequest) {

                //同上

        /**

         * 監聽其他事件

         */

        //添加用戶端連接配接事件

        server.addConnectListener(new ConnectListener() {

            @Override

            public void onConnect(SocketIOClient client) {

                // TODO Auto-generated method stub

                String sa = client.getRemoteAddress().toString();

                String clientIp = sa.substring(1,sa.indexOf(":"));//擷取裝置ip

                System.out.println(clientIp+"-------------------------"+"用戶端已連接配接");

                Map params = client.getHandshakeData().getUrlParams();

                //給用戶端發送消息

                client.sendEvent("advert_info",clientIp+"用戶端你好,我是服務端,有什麼能幫助你的?");

            }

        });

        //添加用戶端斷開連接配接事件

        server.addDisconnectListener(new DisconnectListener(){

            public void onDisconnect(SocketIOClient client) {

                System.out.println(clientIp+"-------------------------"+"用戶端已斷開連接配接");

                client.sendEvent("advert_info",clientIp+"用戶端你好,我是服務端,期待下次和你見面");

          server.start();

        Thread.sleep(Integer.MAX_VALUE);

        server.stop();

    }

}

socketio用戶端:SocketIo_Client.java

import io.socket.client.IO;

import io.socket.client.Socket;

import io.socket.emitter.Emitter;

public class SocketIo_Client {

    public static void main(String[] args) {

        try{

            IO.Options options = new IO.Options();    

            options.forceNew = true;

            options.reconnection = true;

            final Socket socket = IO.socket("http://localhost:9092?deviceId=ZYLPC", options);

            socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {

                @Override

                public void call(Object... args) {

                    System.out.println("connect");

//                    socket.close();

                }

            }).on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {

                @Override 

                    System.out.println("connect timeout");

            }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {

                @Override    

                    System.out.println("connect error");

            }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {

                public void call(Object... args) {    

                    System.out.println("disconnect");

            }).on("advert_info", new Emitter.Listener() {

                @Override

                public void call(Object... args) {

                    String data = (String)args[0];

                    System.out.println("服務端:************"+data.toString());

                    //給服務端發送資訊

                    socket.emit("advert_info", "服務端你好,我是用戶端,我有問題想咨詢你!");

                }

            }).on("notice_info", new Emitter.Listener(){

                public void call(Object... args){

            });

            socket.open();

        }catch(Exception e){

        }

與spring內建:

服務層:SocketIoService.java

import java.util.Collection;

import java.util.HashMap;

import java.util.List;

import org.springframework.stereotype.Service;

@Service("socketIoService")

public class SocketIoService {

    static SocketIOServer server;

    static Map<String, SocketIOClient> clientsMap = new HashMap<String, SocketIOClient>();

    public void startServer() throws InterruptedException{

        //伺服器主機ip    

        //端口

        server = new SocketIOServer(config);

                //擷取用戶端連接配接的uuid參數

                Object object = params.get("uuid");

                String uuid = "";

                if(object != null){

                    uuid = ((List<String>)object).get(0);

                    //将uuid和連接配接用戶端對象進行綁定

                    clientsMap.put(uuid,client);

                }

    public void stopServer(){

        if(server != null){

            server.stop();

            server = null;

    /**

     *  給所有連接配接用戶端推送消息

     * @param eventType 推送的事件類型

     * @param message  推送的内容

     */

    public void sendMessageToAllClient(String eventType,String message){

        Collection<SocketIOClient> clients = server.getAllClients();

        for(SocketIOClient client: clients){

            client.sendEvent(eventType,message);

     * 給具體的用戶端推送消息

     * @param deviceId 裝置類型

     * @param eventType推送事件類型

     * @param message 推送的消息内容

    public void sendMessageToOneClient(String uuid,String eventType,String message){

        try {

            if(uuid != null && !"".equals(uuid)){

                SocketIOClient client = (SocketIOClient)clientsMap.get(uuid);

                if(client != null){

                    client.sendEvent(eventType,message);

        } catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

   public static SocketIOServer getServer() {

        return server;

控制層層:SocketIoController.java

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class SocketIoController {

    @Autowired

    private SocketIoService service;

    //啟動socket 服務

    @RequestMapping("startServer")

    public void startServer(HttpServletRequest request,HttpServletResponse response) throws Exception{

        Map params = ReflectUtil.transToMAP(request.getParameterMap());

            if(service.getServer() == null){

                new Thread(new Runnable() {

                    @Override

                    public void run() {

                        // TODO Auto-generated method stub

                        try {

                            service.startServer();

                        } catch (InterruptedException e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                        }

                    }

                }).start();

    //停止socket服務

    @RequestMapping("stopServer")

    public void stopServer(HttpServletRequest request,HttpServletResponse response) throws Exception{

                service.stopServer();

    //給指定的用戶端推送消息

    @RequestMapping("sendAdvertInfoMsg")

    public void sendAdvertInfoMsg(HttpServletRequest request,HttpServletResponse response) throws Exception{

        String uuid = ParamsUtil.nullDeal(params, "uuid", "");

            if(!"".equals(uuid) && service.getServer() != null){

                service.sendMessageToOneClient(uuid, "advert_info", "推送的内容");

如果想在spring容器啟動之後啟動sockerio,可以這樣做:

自定義一個類,用@component注入

@component (把普通pojo執行個體化到spring容器中,相當于配置檔案中的<bean id="" class=""/>      

實作spring  ApplicationListener接口,這樣在spring加載成功之後就會調用onApplicationEvent方法啟動socketio

import org.springframework.context.ApplicationListener;

import org.springframework.context.event.ContextRefreshedEvent;

import org.springframework.stereotype.Component;

import com.zkkj.backend.common.socketio.BinaryEventLauncher;

import com.zkkj.backend.service.biz.advert.IAdvertService;

/**

 * spring加載完畢後執行

 * @author ZYL_PC

 *

 */

@Component("BeanDefineConfigue")

public class BeanDefineConfigue  implements ApplicationListener<ContextRefreshedEvent>{

    @Autowired

    //目前伺服器的ip

    private String serverIp = "";

    //目前伺服器裝置id

    private String deviceId = "";

    //執行時間,時間機關為毫秒,讀者可自行設定,不得小于等于0

    private static Long cacheTime = Long.MAX_VALUE;

    //延遲時間,時間機關為毫秒,讀者可自行設定,不得小于等于0

    private static Integer delay = 3000;

    @Override

    public void onApplicationEvent(ContextRefreshedEvent event) {

        // TODO Auto-generated method stub

        Timer timer = new Timer();

        timer.scheduleAtFixedRate(new TimerTask() {

          public void run() {

            //啟動socket監聽

              try{

                  if(service.getServer() == null){

                      new Thread(new Runnable() {

                          @Override

                          public void run() {

                              try {

                                  service.startServer();

                              } catch (InterruptedException e) {

                                  e.printStackTrace();

                              }

                          }

                      }).start();

                  }

              }catch(Exception e){

              }

          }

        }, delay,cacheTime);// 這裡設定将延時每天固定執行