×

maven 即时通讯 websocket

建了一个maven聚合工程,打算开发一个web即时通信项目

我的笔记 我的笔记 发表于2019-01-11 17:30:01 浏览3197 评论0

抢沙发发表评论

    闲来无事,偶尔看到一片文章,讲的是websocket和http轮询的优势,正好,我对此有一定的兴趣,决定搭建一个项目来实现web页面下的即时通信。

    先给大家介绍一下websocket和轮训长轮询,直接粘贴。

轮询

轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏览器需要不断的向服务器发出请求,然而HTTP request 的header是非常长的,里面包含的有用数据可能只是一个很小的值,这样会占用很多的带宽。

var xhr = new XMLHttpRequest();
    setInterval(function(){
        xhr.open('GET','/user');
        xhr.onreadystatechange = function(){

        };
        xhr.send();
    },1000)

长轮询:

ajax实现:在发送ajax后,服务器端会阻塞请求直到有数据传递或超时才返回。 客户端JavaScript响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。

    function ajax(){        var xhr = new XMLHttpRequest();
        xhr.open('GET','/user');
        xhr.onreadystatechange = function(){
              ajax();
        };
        xhr.send();
    }

Web Socket:

轮询与长轮询都是基于HTTP的,两者本身存在着缺陷:轮询需要更快的处理速度;长轮询则更要求处理并发的能力;两者都是“被动型服务器”的体现:服务器不会主动推送信息,而是在客户端发送ajax请求后进行返回的响应。而理想的模型是"在服务器端数据有了变化后,可以主动推送给客户端",这种"主动型"服务器是解决这类问题的很好的方案。Web Sockets就是这样的方案。
//需要先npm install ws//服务器端var Server = require('ws').Server;var wss = new Server({    port:2000});
wss.on('connection',function(ws){
    ws.on('message',function(data){
        ws.send('你好,客户端,我是服务器!');        console.log(data);
    })
});//node客户端var WebSocket = require('ws');var socket = new WebSocket('ws://localhost:2000/');
socket.on('open',function(){
    socket.send('你好,服务器,我是客户端');
});
socket.on('message',function(event){    console.log(event);
})//html客户端(注:浏览器客户端与node客户端只需要一种)<script>    var socket = new WebSocket('ws://localhost:2000/');
    socket.onopen = function(){

    };
    socket.onmessage = function(event){        console.log(event.data)
    }
</script>


以上呢,只是个简单的例子,给大家了解一下在企业级项目中,消息发送的几种方式。

一、项目框架的选取

    由于第一次一个做这种项目,我想的是为了以后高并发的处理,打算使用分布式,但是分布式很难一下就上手。暂时就先用maven聚合工程来做了,。到后期有时间再改。

    技术包括:maven+springboot+spring security+admin lte(前端)

    首先建了一个父工程,新建一个pom.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
    </parent>
    <groupId>com.fyd</groupId>
    <artifactId>smart-web-im</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <modules>
        <module>smart-web-im-bin</module>
        <module>smart-web-im-common</module>
        <module>smart-web-im-web</module>
        <module>smart-web-im-login</module>
        <module>smart-web-im-base</module>
    </modules>
    <!-- FIXME change it to the project's website -->
    <url>https://www.javagoing.com</url>

    <build>
        <finalName>smart-web-im-root</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${project.build.jdk}</source>
                    <target>${project.build.jdk}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <!-- 配置 -->
    <properties>
        <!-- base setting -->
        <project.build.jdk>1.8</project.build.jdk>
        <example.version>1.0.0-SNAPSHOT</example.version>
        <!-- spring -->
        <spring.boot.version>1.5.6.RELEASE</spring.boot.version>
        <!-- mybatis -->
        <mybatis-spring-boot>1.3.0</mybatis-spring-boot>
        <mybatis.pagehelper.version>1.1.3</mybatis.pagehelper.version>
        <!-- druid -->
        <druid.version>1.1.2</druid.version>
        <!-- DataBase version -->
        <mysql.connector.version>6.0.6</mysql.connector.version>
        <!-- log4j -->
        <slf4j.version>1.7.25</slf4j.version>
        <log4j.version>2.8.2</log4j.version>
        <!-- commons -->
        <commons.fileupload.version>1.3.3</commons.fileupload.version>
        <commons.codec.version>1.10</commons.codec.version>
        <commons.net.version>3.6</commons.net.version>
        <commons.logging.version>1.2</commons.logging.version>
        <commons.collections.version>3.2.2</commons.collections.version>
        <commons.lang3.version>3.6</commons.lang3.version>
        <!-- fastjson -->
        <fastjson.version>1.2.36</fastjson.version>

    </properties>
    <dependencies>
        <!-- spring start -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 这里指定打包的时候不再需要tomcat相关的包 -->
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <!--idea需要注释掉,idea编译的时候找不到provided包-->
            <!--<scope>provided</scope>-->
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- mybatis start -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis-spring-boot}</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>${mybatis.pagehelper.version}</version>
        </dependency>
        <!-- mysql-connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>
        <!-- Druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- Alibaba Fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
        <!-- log start -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- apache start -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons.fileupload.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>${commons.codec.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>${commons.net.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${commons.logging.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>${commons.collections.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons.lang3.version}</version>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--使其不必严格校验html标签-->
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
        </dependency>
        <!-- spring security依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>
</project>

父工程就这一个文件。

接下来是启动模块  我给它命名为smart_web_bin,它的pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>smart-web-im</artifactId>
        <groupId>com.fyd</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <version>${example.version}</version>
    <artifactId>smart-web-im-bin</artifactId>
    <packaging>war</packaging>
    <name>smart-web-im-bin</name>
    <!-- FIXME change it to the project's website -->
    <url>https://www.javagoing.com</url>
    <dependencies>
        <!--web模块引入-->
        <dependency>
            <groupId>com.fyd</groupId>
            <artifactId>smart-web-im-web</artifactId>
            <version>${example.version}</version>
        </dependency>
        <!--base模块引入,一些配置类和共用类-->
        <dependency>
            <groupId>com.fyd</groupId>
            <artifactId>smart-web-im-base</artifactId>
            <version>${example.version}</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <mainClass>com.fyd.Application</mainClass>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
                <!-- maven打包的时候告诉maven不需要web.xml,否刚会报找不到web.xml错误 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.1.0</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>

            </plugins>
        </pluginManagement>
    </build>

</project>

此时的项目结构如下:

image.png

application.yml的内容:

# [Server]
server:
  address: 127.0.0.1
  port: 9900
  context-path: /im
  session:
    timeout: -1
    tracking-modes: cookie
  tomcat:
    max-threads: 100
    uri-encoding: UTF-8
# [Spring]
spring:
  datasource:
    url: jdbc:mysql://javagoing.com:33061/smart_web_im?useUnicode=true&characterEncoding=UTF-8
    data-username: root
    data-password: fuyadong
    driver-class-name: com.mysql.cj.jdbc.Driver
    schema: classpath*:schema-*.sql
    initialize: false
    continue-on-error: false
  # [thymeleaf静态资源配置]
  thymeleaf:
    prefix: classpath:/WEB-INF/templates/
    suffix: .html
    mode: LEGACYHTML5
    encoding: UTF-8
    content-type: text/html
    cache: false

Application.java内容如下:

/*
 * All rights Reserved, Designed By DataDriver
 * Copyright:    DataDriver.Inc
 * Company:      Zhuo Wo Infomation Technology (ShangHai) CO.LTD
 */
package com.fyd;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SpringBootApplication
@EnableAutoConfiguration
public class Application  extends WebMvcConfigurerAdapter {
    /***
     * 配置静态访问资源
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if(!registry.hasMappingForPattern("/static/**")){
            registry.addResourceHandler("/static/**").addResourceLocations("classpath:/WEB-INF/static/");
        }
        super.addResourceHandlers(registry);
    }
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

至此。运行main方法就可以启动该项目。


ps:敲黑板!!!!!(在idea中会碰到各种各样的问题)

    碰到很多坑,聚合项目有时候改完不能立刻生效:

image.png

需要先:clean,compile,install,才行。。。


还有时候,新建的模块不能被扫描到controller,server等注解类:

需要下面这样操作:reimport,更新一下maven项目

image.png



我的笔记博客版权我的笔记博客版权