歡迎您光臨本站 註冊首頁

反應式微框架 Reactor-Guice 0.12.5, 修復 websocket 連接退出

←手機掃碼閱讀     admin @ 2020-02-07 , reply:0

Reactor-guice 是一個基於 Google Guice 和 Reactor-netty 的 反應式微服務框架

設計為大家喜歡的通過註解來配置路由,性能基於反應式框架的特點,非常的高效。

對於 web 開發常見的 Json, Protobuf, 表單,文件上傳,websocket ,都是輕鬆支持

0.0.3 註冊註解 @GET @POST @PUT @DELETE @Products @PATH

  • 支持 Websocket 可作為靜態文件服
  • 支持對 URI Filter 處理

0.0.5 靜態文件目錄后默認輸出 index.html

  • 支持自選模板引擎,自帶Freemark Thymeleaf 處理類
  • 支持自定義Json引擎,自帶 Gson 和jackson 的處理類
  • 添加 ModelMap, 注入到 Controlle 的方法,用戶模板的變數代入
  • 可以上傳文件了

0.0.8 可以 POST 數組

  • 通過返回 Mono.just("redirect:/...") 實現重定向
  • 支持 API 網關模式
  • 修復頭信息錯誤的 BUG
  • 可選返回跨域頭信息

0.10  支持輸出 Protobuf

  • BeanParm 可以支持 Form ,Json Protobuf ,將上傳的數據自動組織成對象
  • 上傳的文件接受類型 byte[] , UploadFile, File
  • 上傳文件可以自動保存到指定的目錄

0.11  增加自動掃描 Controlle 類和 Service

  • 通過掃描完成路由配置和依賴注入,不同手動做額外配置

0.12.1 靜態文件的讀取塞入到非同步中去處理

  • 這個版本是一個穩定的版本

0.12.2 優化 Jar 內讀取文件的變數

  • 簡化 websocket 的介面
  • 網關模式增加 websocket

0.12.4 增加 Https (0.12.3)

  • 靜態文件目錄可配置多個
  • 修復上傳文件多次后,溢出的情況,補充 FileUpload.release()
  • 修復非 Form POST ,錯誤的做了 Bytebuf.release()

0.12.5 修復 websocket 長鏈接 bug

1. 引入 reactor-guice

maven


<dependency>
    <groupId>com.doopp</groupId>
    <artifactId>reactor-guice</artifactId>
    <version>0.12.5</version>
</dependency>

gradle


compile 'com.doopp:reactor-guice:0.12.5'

2. 創建應用


public static void main(String[] args) throws IOException {
        // 載入配置
        Properties properties = new Properties();
        properties.load(new FileInputStream(args[0]));

        String host = properties.getProperty("server.host");
        int port = Integer.valueOf(properties.getProperty("server.port"));
        // 啟動服務
        ReactorGuiceServer.create()
                .bind(host, port)
                .createInjector(
                        // 方便使用 @Names 來獲取配置 
                        binder -> Names.bindProperties(binder, properties),
                        // 資料庫
                        new MyBatisModule() {
                            @Override
                            protected void initialize() {
                                install(JdbcHelper.MySQL);
                                bindDataSourceProviderType(HikariDataSourceProvider.class);
                                bindTransactionFactoryType(JdbcTransactionFactory.class);
                                addMapperClasses("com.doopp.gauss.app.dao");
                                // addInterceptorClass(PageInterceptor.class);
                            }
                        },
                        // Redis    
                        new RedisModule(),
                        // 自定義的配置
                        new ApplicationModule()
                )
                // 配置 Json 處理類
                .setHttpMessageConverter(new MyGsonHttpMessageConverter())
                // 設定自動掃描 Controller 和 Service 的包名,可以配置多個
                .basePackages("com.doopp.gauss.app", ...)
                // 配置多個靜態資源
                .addResource("/static/", "/static-public/")
                .addResource("/", "/public/")
                // https
                .setHttps(new File(jksFilePath), jksPassword, jksSecret)
                // 目前僅支持通過 URI 來過濾,可以多次 addFilter
                .addFilter("/", AppFilter.class)
                // 錯誤信息輸出
                .printError(true)
                .launch();
    }

3. 創建 Controller

Controller Example


@Controller
@Path("/api/admin")
public class ExampleController {

    @GET
    @Path("/json")
    @Produces({MediaType.APPLICATION_JSON})
    public Mono<Map<String, String>> json() {
        return Mono
            .just(new HashMap<String, String>())
            .map(m -> {
                m.put("hi", "five girl");
                return m;
            });
    }

    @GET
    @Path("/jpeg")
    @Produces({"image/jpeg"})
    public Mono<ByteBuf> jpeg() {
        return HttpClient.create()
            .get()
            .uri("https://static.cnbetacdn.com/article/2019/0402/6398390c491f650.jpg")
            .responseContent()
            .aggregate()
            .map(ByteBuf::retain);
    }
}

WebSocket


@Path("/kreactor/ws")
@Singleton
public class WsTestHandle extends AbstractWebSocketServerHandle {

    @Override
    public void connected(Channel channel) {
        System.out.println(channel.id());
        super.connected(channel);
    }

    @Override
    public void onTextMessage(TextWebSocketFrame frame, Channel channel) {
        System.out.println(frame.text());
        super.onTextMessage(frame, channel);
    }
}

Api Gateway 模式


ReactorGuiceServer.create()
        .bind(host, port)
        .setApiGatewayDispatcher(new MyApiGatewayDispatcher())
        .addFilter("/", TestFilter.class)
        .launch();

混合的 Api Gateway Model


ReactorGuiceServer.create()
        .bind(host, port)
        .createInjector(module1, module2, ...)
        .setHttpMessageConverter(new JacksonHttpMessageConverter())
        .setApiGatewayDispatcher(new MyApiGatewayDispatcher())
        .handlePackages("com.doopp.reactor.guice.test")
        .addFilter("/", TestFilter.class)
        .launch();

表單和文件上傳


// Server
@POST
@Path("/test/post-bean")
public Mono<User> testPostBean(@BeanParam User user, @FileParam(value="image", path = "C:\\Users\\koocyton\\Desktop") File[] file) {
    return Mono.just(user);
}

// Client Test
@Test
public void testFileUpload() {

    String hhe = HttpClient.create()
        .post()
        .uri("http://127.0.0.1:8083/kreactor/test/post-bean")
        .sendForm((req, form) -> form.multipart(true)
            .attr("id", "123123121312312")
            .attr("account", "account")
            .attr("password", "password")
            .attr("name", "name")
            .file("image", new File("C:\\Users\\koocyton\\Pictures\\cloud.jpg"))
            .file("image", new File("C:\\Users\\koocyton\\Pictures\\st.jpg"))
        )
        .responseSingle((res, content) -> content)
        .map(byteBuf -> byteBuf.toString(CharsetUtil.UTF_8))
        .block();

    System.out.println(hhe);
}

Protobuf


// Server
@POST
@Path("/test/proto-post-bean")
public Mono<Hello> testPostBean(@BeanParam Hello hello) {
    return Mono.just(hello);
}

// Test Client
@Test
public void testPostProtobufBean() {

    Hello.Builder builder = Hello.newBuilder();
    builder.setId(123);
    builder.setName("wuyi");
    builder.setEmail("wuyi@doopp.com");

    ByteBuf buf = Unpooled.wrappedBuffer(builder.build().toByteArray()).retain();

        String hhe = HttpClient.create()
            .headers(headers -> {
                headers.add(HttpHeaderNames.CONTENT_TYPE, "application/x-protobuf");
            })
            .post()
            .uri("http://127.0.0.1:8083/kreactor/test/proto-post-bean")
            .send(Flux.just(buf.retain()))
            .responseSingle((res, content) -> content)
            .map(byteBuf -> byteBuf.toString(CharsetUtil.UTF_8))
            .block();

        System.out.println(hhe);
}

[admin ]

來源:OsChina
連結:https://www.oschina.net/news/113224/reactor-guice-0-12-5-released
反應式微框架 Reactor-Guice 0.12.5, 修復 websocket 連接退出已經有91次圍觀

http://coctec.com/news/all/show-post-224322.html