You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by la...@apache.org on 2021/07/25 14:35:45 UTC

[dubbo-go-samples] branch 3.0 updated: Fix: fix 3.0 branch game integrate error & delete useless file (#185)

This is an automated email from the ASF dual-hosted git repository.

laurence pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new de22699  Fix: fix 3.0 branch game integrate error & delete useless file (#185)
de22699 is described below

commit de22699e6e0524a299a0db95fc511031de69b406
Author: 氕氘氚 <cj...@163.com>
AuthorDate: Sun Jul 25 22:35:35 2021 +0800

    Fix: fix 3.0 branch game integrate error & delete useless file (#185)
    
    * fix game integrate error & del useless file
    
    * fix imports error
---
 .run/game-go-game-test.run.xml                     |  17 --
 .run/game-go-gate-test.run.xml                     |  17 --
 game/README.md                                     | 294 +++++++++++++++++++-
 game/README_zh.md                                  | 298 ++++++++++++++++++++-
 game/go-server-game/cmd/server.go                  |  23 +-
 game/go-server-game/conf/test_client.yml           |  75 ------
 game/go-server-game/pkg/consumer.go                |   6 +-
 game/go-server-game/pkg/main.go                    |  20 --
 game/go-server-game/pkg/provider.go                | 133 +++++----
 .../tests/integration/gameprovider_test.go         |  30 +--
 game/go-server-game/tests/integration/main_test.go |   7 +-
 game/go-server-gate/cmd/server.go                  |  88 +++++-
 game/go-server-gate/conf/test_client.yml           |  67 -----
 game/go-server-gate/pkg/consumer.go                |  17 +-
 game/go-server-gate/pkg/main.go                    |  20 --
 game/go-server-gate/pkg/provider.go                |  11 -
 .../tests/integration/gateprovider_test.go         |   0
 game/go-server-gate/tests/integration/main_test.go |   4 +-
 game/pkg/consumer/game/basketball.go               |   6 +-
 game/pkg/consumer/game/jump.go                     |  19 --
 game/pkg/consumer/gate/basketball.go               |   0
 game/pkg/consumer/gate/jump.go                     |  17 --
 game/pkg/pojo/info.go                              |  10 +
 game/website/css/style.css                         |  54 ++++
 game/website/img/bac.png                           | Bin 0 -> 313830 bytes
 game/website/index.html                            |  56 ++++
 game/website/js/api.js                             |  64 +++++
 game/website/js/index.js                           | 130 +++++++++
 start_integrate_test.sh                            |   4 +
 29 files changed, 1116 insertions(+), 371 deletions(-)

diff --git a/.run/game-go-game-test.run.xml b/.run/game-go-game-test.run.xml
deleted file mode 100644
index 0da8e8e..0000000
--- a/.run/game-go-game-test.run.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="game-go-game-test" type="GoTestRunConfiguration" factoryName="Go Test">
-    <module name="dubbo-go-samples" />
-    <working_directory value="$PROJECT_DIR$/game" />
-    <useCustomBuildTags value="true" />
-    <envs>
-      <env name="CONF_CONSUMER_FILE_PATH" value="go-server-game/conf/test_client.yml" />
-      <env name="APP_LOG_CONF_FILE" value="go-server-game/conf/log.yml" />
-    </envs>
-    <framework value="gotest" />
-    <kind value="PACKAGE" />
-    <package value="github.com/apache/dubbo-go-samples/game/go-server-game/tests/integration" />
-    <directory value="$PROJECT_DIR$" />
-    <filePath value="$PROJECT_DIR$" />
-    <method v="2" />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/.run/game-go-gate-test.run.xml b/.run/game-go-gate-test.run.xml
deleted file mode 100644
index df0b5ce..0000000
--- a/.run/game-go-gate-test.run.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="game-go-gate-test" type="GoTestRunConfiguration" factoryName="Go Test">
-    <module name="dubbo-go-samples" />
-    <working_directory value="$PROJECT_DIR$/game" />
-    <useCustomBuildTags value="true" />
-    <envs>
-      <env name="CONF_CONSUMER_FILE_PATH" value="go-server-gate/conf/test_client.yml" />
-      <env name="APP_LOG_CONF_FILE" value="go-server-gate/conf/log.yml" />
-    </envs>
-    <framework value="gotest" />
-    <kind value="PACKAGE" />
-    <package value="github.com/apache/dubbo-go-samples/game/go-server-gate/tests/integration" />
-    <directory value="$PROJECT_DIR$" />
-    <filePath value="$PROJECT_DIR$" />
-    <method v="2" />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/game/README.md b/game/README.md
old mode 100644
new mode 100755
index 571e070..18e6389
--- a/game/README.md
+++ b/game/README.md
@@ -6,7 +6,297 @@
 - The two services communicate with each other RPC (both registered **provider** and **consumer**)
 - The **gate** additionally starts the http service (port **8000**), which is used to manually trigger the **gate** RPC to call **game**
 
-> After each **gate** RPC call (**Message**) **game**, **game** will synchronize the RPC call (Send) **gate** pushes the same message
-> This logic is annotated by default, and the location is `go-server-game/pkg/provider.go` (line 25 ~ 30)
+> Each time **gate** RPC calls (**message**) **game**, **game** will synchronously call RPC (send) **gate** to push the same message. 
+
+### outline
+
+Catalog description
+
+```shell
+├── go-server-game    # game module
+│   ├── cmd           # Main entrance
+│   ├── conf          # configuration file
+│   ├── docker        # docker-compose config file
+│   ├── pkg           # provider and consumer
+│   └── tests
+├── go-server-gate    # gate module
+│   ├── cmd           # Main entrance
+│   ├── conf          # configuration file
+│   ├── docker        # docker-compose config file
+│   ├── pkg           # provider and consumer
+│   └── tests
+└── pkg
+    ├── consumer      # public consumer
+    │   ├── game
+    │   └── gate
+    └── pojo
+```
+
+Process of initiating HTTP service
+
+<img src="http://cdn.cjpa.top/cdnimages/image-20210424095907886.png" alt="image-20210424095907886" style="zoom: 33%;" />
+
+
+
+From the perspective of consumer and provider, the process of initiating a call is as follows.
+
+<img src="http://cdn.cjpa.top/cdnimages/image-20210424100148028.png" alt="image-20210424100148028" style="zoom:33%;" />
+
+Game provides the basketball server and gate provides the HTTP server.
+
+### game module
+
+#### server side
+
+The server provides three services, message, online and offline. The code is as follows. The specific implementation can be in  game/go-server-game/pkg/provider.go see in.
+
+```go
+type BasketballService struct{}
+
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    ...
+}
+
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    ...
+}
+
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    ...
+}
+
+func (p *BasketballService) Reference() string {
+    return "gameProvider.basketballService"
+}
+```
+
+##### configuration file
+
+Register the service in the configuration file, where gameProvider.basketballService Same as declared in the reference method.
+
+```yml
+services:
+  "gameProvider.basketballService":
+    registry: "demoZk"
+    protocol: "dubbo"
+    interface: "org.apache.dubbo.game.BasketballService"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+      - name: "Online"
+        retries: 0
+      - name: "Offline"
+        retries: 0
+      - name: "Message"
+        retries: 
+```
+
+#### consumer side
+
+The consumer of basketball is mainly used to be called by gate, so the main code is put in 'game/pkg/consumer/gate/basketball.go',  The consumer code is as follows.
+
+```go
+type BasketballService struct {
+    Send func(ctx context.Context, uid string, data string) (*pojo.Result, error)
+}
+
+func (p *BasketballService) Reference() string {
+    return "gateConsumer.basketballService"
+}
+```
+
+In basketball, you only need to instantiate a consumer variable.
+
+```go
+var gateBasketball = new(gate.BasketballService)
+```
+
+Then register to Dubbo go in main.
+
+```go
+config.SetConsumerService(gateBasketball)
+```
+
+##### configuration file
+
+```yml
+references:
+  "gateConsumer.basketballService":
+    registry: "demoZk"
+    protocol : "dubbo"
+    interface : "org.apache.dubbo.gate.BasketballService"
+    cluster: "failover"
+    methods:
+      - name: "Send"
+        retries: 0
+```
+
+Because the consumer of game needs to call the provider of gate, the string returned by the reference method is gateConsumer.basketballService , in the configuration file gateConsumer.basketballService And 'game/pkg/consumer/gate/basketball.go'. The value of interface should be consistent with that of the provider of gate.
+
+### gate module
+
+#### server side
+
+```go
+type BasketballService struct{}
+
+func (p *BasketballService) Send(ctx context.Context, uid, data string) (*pojo.Result, error) {
+...
+}
+
+func (p *BasketballService) Reference() string {
+    return "gateProvider.basketballService"
+}
+```
+
+Register with Dubbo
+
+```go
+config.SetProviderService(new(BasketballService))
+```
+
+##### configuration file
+
+gateProvider.basketballService  The interface here must be the same as that in game client.yml  The settings in the file should be consistent, otherwise game cannot send data to gate.
+
+```yml
+# service config
+services:
+  "gateProvider.basketballService":
+    registry: "demoZk"
+    protocol : "dubbo"
+    interface : "org.apache.dubbo.gate.BasketballService"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+      - name: "Send"
+        retries: 0
+```
+
+#### consumer side
+
+The consumer side of the gate is relatively special. Because the consumer of the gate needs to call the service in the game, the consumer directly instantiates the service of a game, and its method directly uses the instantiated object gamebasketball to call, thus realizing the function of a gateway.
+
+```go
+var GameBasketball = new(game.BasketballService)
+
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    return GameBasketball.Login(ctx, data)
+}
+
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    return GameBasketball.Score(ctx, uid, score)
+}
+
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    return GameBasketball.Rank(ctx, uid)
+}
+```
+
+In code GameBasketball.Message、GameBasketball.Online、GameBasketball.Offline , all the methods called are game methods.
+Register with dubbo
+
+```go
+config.SetProviderService(new(pkg.BasketballService))
+```
+
+##### configuration file
+
+The inerface in the configuration file should also be consistent with the game provider, otherwise the gate cannot be called after receiving the HTTP request.
+
+```yml
+references:
+  "gameConsumer.basketballService":
+    registry: "demoZk"
+    protocol : "dubbo"
+    interface : "org.apache.dubbo.game.BasketballService"
+    cluster: "failover"
+    methods:
+      - name: "Online"
+        retries: 0
+      - name: "Offline"
+        retries: 0
+      - name: "Message"
+        retries: 0
+```
+
+### HTTP access
+
+access login
+
+```bash
+curl --location --request GET 'http://127.0.0.1:8089/login?name=dubbogo'
+```
+
+received
+
+```json
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
+```
+
+
+
+access score
+
+```bash
+curl --location --request POST 'http://127.0.0.1:8089/score' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+    "name":"cjp",
+    "score":1
+}'
+```
+
+received
+
+```json
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
+```
+
+access rank
+
+```bash
+curl --location --request POST 'http://127.0.0.1:8089/rank?name=dubbogo'
+```
+
+received
+
+```json
+{
+    "code": 0,
+    "msg": "success",
+    "data": {
+        "rank": 3,
+        "to": "dubbogo"
+    }
+}
+```
+
+It can be found that all HTTP requests are successfully forwarded to game, and the processed data is returned to gate by calling the send method of gate
+
+
+
+### Start the front end
+
+Switch to webside directory and open index.html (Chrome browser is recommended)
+
+![image-20210516173728198](http://cdn.cjpa.top/image-20210516173728198.png)
 
 Pls. refer to [HOWTO.md](../HOWTO.md) under the root directory to run this sample.
+
diff --git a/game/README_zh.md b/game/README_zh.md
old mode 100644
new mode 100755
index 5071900..1b4592d
--- a/game/README_zh.md
+++ b/game/README_zh.md
@@ -4,10 +4,304 @@
 
 - 示例包含 **gate** (网关服务) 和 **game** (逻辑服务) 两个服务
 - 两个服务会互相 RPC 通讯 (都同时注册 **provider** 和 **consumer**)
-- **gate** 额外启动了 http 服务 (端口 **8000**), 用于手工触发 **gate** RPC调用 **game**
+- **gate** 额外启动了 http 服务 (端口 **8000**), 用于手工触发  **gate** RPC 调用 **game**
 
 > 每次 **gate** RPC调用(**Message**) **game** 后, **game** 会同步RPC调用(Send) **gate** 推送相同消息
-> 此逻辑默认已注释, 位置在 `go-server-game/pkg/provider.go` (25 ~ 30行)
 
+### 概要
+
+目录说明
+
+```bash
+├── go-server-game    # game模块
+│   ├── cmd           # 主入口
+│   ├── conf          # 配置文件
+│   ├── docker        # docker-compose文件
+│   ├── pkg           # provider和consumer
+│   └── tests
+├── go-server-gate    # gate模块
+│   ├── cmd           # 主入口
+│   ├── conf          # 配置文件
+│   ├── docker        # docker-compose文件
+│   ├── pkg           # provider和consumer
+│   └── tests
+└── pkg
+    ├── consumer      # 公共consumer
+    │   ├── game
+    │   └── gate
+    └── pojo
+```
+
+发起http服务的流程
+
+<img src="http://cdn.cjpa.top/cdnimages/image-20210423212453935.png" alt="image-20210423212453935" style="zoom:50%;" />
+
+
+
+从consumer和provider角度来看,发起一次调用的流程是这样的
+
+<img src="http://cdn.cjpa.top/cdnimages/image-20210424094134541.png" alt="image-20210424094134541" style="zoom: 33%;" />
+
+game提供了basketball服务端,gate提供了http服务端。
+
+### game模块
+
+#### server端
+
+server 端提供三个服务,Login、Score 及 Rank,代码如下,具体的实现可以在 'game/go-server-game/pkg/provider.go' 中看到
+
+```go
+type BasketballService struct{}
+
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    ...
+}
+
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    ...
+}
+
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    ...
+}
+
+func (p *BasketballService) Reference() string {
+    return "gameProvider.basketballService"
+}
+```
+
+##### 配置文件
+
+ 在配置文件中注册 service,其中 gameProvider.basketballService 和 Reference 方法中声明的一致。
+
+```yml
+services:
+  "gameProvider.basketballService":
+    registry: "demoZk"
+    protocol: "dubbo"
+    interface: "org.apache.dubbo.game.BasketballService"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+      - name: "Online"
+        retries: 0
+      - name: "Offline"
+        retries: 0
+      - name: "Message"
+        retries: 
+```
+
+#### consumer端
+
+basketball 部分的 consumer 主要用来被 gate 调用,因此主要代码放在了 'game/pkg/consumer/gate/basketball.go' 中,这部分作为公共部分,consumer 代码如下
+
+```go
+type BasketballService struct {
+    Send func(ctx context.Context, uid string, data string) (*pojo.Result, error)
+}
+
+func (p *BasketballService) Reference() string {
+    return "gateConsumer.basketballService"
+}
+```
+
+在basketball中,只需要实例化一个consumer变量即可
+
+```go
+var gateBasketball = new(gate.BasketballService)
+```
+
+然后在main中注册到dubbo-go
+
+```go
+config.SetConsumerService(gateBasketball)
+```
+
+##### 配置文件
+
+```yml
+references:
+  "gateConsumer.basketballService":
+    registry: "demoZk"
+    protocol : "dubbo"
+    interface : "org.apache.dubbo.gate.BasketballService"
+    cluster: "failover"
+    methods:
+      - name: "Send"
+        retries: 0
+```
+
+由于 game 的 consumer 需要调用 gate 的provider,因此 Reference 方法返回的字符串为 gateConsumer.basketballService ,在配置文件中 gateConsumer.basketballService 和 'game/pkg/consumer/gate/basketball.go' 中Reference 方法声明的一致,intreface 的值也要和 gate 的 provider 设置的一致。
+
+### gate模块
+
+#### server端
+
+```go
+type BasketballService struct{}
+
+func (p *BasketballService) Send(ctx context.Context, uid, data string) (*pojo.Result, error) {
+...
+}
+
+func (p *BasketballService) Reference() string {
+    return "gateProvider.basketballService"
+}
+```
+
+注册到dubbo
+
+```go
+config.SetProviderService(new(BasketballService))
+```
+
+##### 配置文件
+
+gateProvider.basketballService 和 Reference 中的一致,这里的 interface 一定要和 game 的 client.yml 文件中设置的保持一致,不然 game 无法向 gate 发送数据
+
+```yml
+# service config
+services:
+  "gateProvider.basketballService":
+    registry: "demoZk"
+    protocol : "dubbo"
+    interface : "org.apache.dubbo.gate.BasketballService"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+      - name: "Send"
+        retries: 0
+```
+
+#### consumer端
+
+gate 中的 consumer 端比较特殊,由于 gate的consumer 需要调用 game 中的 service,所以在gaet中,consumer 直接实例化一个game的service,其方法便直接使用实例化的对象 GameBasketball 调用,这样就实现了一个网关的功能。
+
+```go
+var GameBasketball = new(game.BasketballService)
+
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    return GameBasketball.Login(ctx, data)
+}
+
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    return GameBasketball.Score(ctx, uid, score)
+}
+
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    return GameBasketball.Rank(ctx, uid)
+}
+```
+
+代码中的 GameBasketball.Message、GameBasketball.Online、GameBasketball.Offline 调用的方法都是 game 的方法
+
+注册到dubbo
+
+```go
+config.SetProviderService(new(pkg.BasketballService))
+```
+
+##### 配置文件
+
+配置文件中的 inerface 也要和 game 的 provider 保持一致,不然收到 http 请求之后无法调用 gate
+
+```yml
+references:
+  "gameConsumer.basketballService":
+    registry: "demoZk"
+    protocol : "dubbo"
+    interface : "org.apache.dubbo.game.BasketballService"
+    cluster: "failover"
+    methods:
+      - name: "Online"
+        retries: 0
+      - name: "Offline"
+        retries: 0
+      - name: "Message"
+        retries: 0
+```
+
+
+
+### HTTP访问
+
+访问login
+
+```bash
+curl --location --request GET 'http://127.0.0.1:8089/login?name=dubbogo'
+```
+
+收到账户的信息
+
+```json
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
+```
+
+
+
+访问 score
+
+```bash
+curl --location --request POST 'http://127.0.0.1:8089/score' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+    "name":"cjp",
+    "score":1
+}'
+```
+
+收到
+
+```json
+{
+    "code": 0,
+    "msg": "dubbogo, your score is 0",
+    "data": {
+        "score": 0,
+        "to": "dubbogo"
+    }
+}
+```
+
+访问 rank
+
+```http
+curl --location --request POST 'http://127.0.0.1:8089/rank?name=dubbogo'
+```
+
+收到
+
+```json
+{
+    "code": 0,
+    "msg": "success",
+    "data": {
+        "rank": 3,
+        "to": "dubbogo"
+    }
+}
+```
+
+可以发现,所有的http请求,都成功的转发到了 game,并且又通过调用 gate 的 send 方法把处理过的数据返回给 gate
+
+
+
+### 启动前端
+
+切换到 webside 目录,打开 index.html 即可(推荐使用chrome浏览器)
+
+![image-20210516173728198](http://cdn.cjpa.top/image-20210516173728198.png)
+
+点击小人即可进行游戏
 
 请参阅根目录中的 [HOWTO.md](../HOWTO_zh.md) 来运行本例。
+
diff --git a/game/go-server-game/cmd/server.go b/game/go-server-game/cmd/server.go
old mode 100644
new mode 100755
index 00a785c..e0853a8
--- a/game/go-server-game/cmd/server.go
+++ b/game/go-server-game/cmd/server.go
@@ -5,24 +5,37 @@ import (
 	"os/signal"
 	"syscall"
 	"time"
-)
 
-import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+
 	_ "dubbo.apache.org/dubbo-go/v3/cluster/cluster_impl"
+
 	_ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
 	"dubbo.apache.org/dubbo-go/v3/common/logger"
+
 	_ "dubbo.apache.org/dubbo-go/v3/common/proxy/proxy_factory"
 	"dubbo.apache.org/dubbo-go/v3/config"
+
 	_ "dubbo.apache.org/dubbo-go/v3/filter/filter_impl"
+
 	_ "dubbo.apache.org/dubbo-go/v3/metadata/service/local"
+
 	_ "dubbo.apache.org/dubbo-go/v3/protocol/dubbo"
+
 	_ "dubbo.apache.org/dubbo-go/v3/registry/protocol"
+
 	_ "dubbo.apache.org/dubbo-go/v3/registry/zookeeper"
+	"github.com/apache/dubbo-go-samples/game/go-server-game/pkg"
+	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
 )
 
-import (
-	_ "github.com/apache/dubbo-go-samples/game/go-server-game/pkg"
-)
+func init() {
+	config.SetProviderService(new(pkg.BasketballService))
+
+	config.SetConsumerService(pkg.GateBasketball)
+
+	hessian.RegisterPOJO(&pojo.Result{})
+}
 
 func main() {
 	config.Load()
diff --git a/game/go-server-game/conf/test_client.yml b/game/go-server-game/conf/test_client.yml
deleted file mode 100644
index 90674d8..0000000
--- a/game/go-server-game/conf/test_client.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-# dubbo client yaml configure file
-
-check: false
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application:
-  organization : "dubbo.io"
-  name  : "GameServiceTest"
-  module : "dubbo-go game service client"
-  version : "0.0.1"
-  environment : "dev"
-
-# registry config
-registries :
-  "demoZk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2181"
-    username: ""
-    password: ""
-
-# reference config
-references:
-  "gameConsumer.basketballService":
-    registry: "demoZk"
-    protocol : "dubbo"
-    interface : "org.apache.dubbo.game.BasketballService"
-    cluster: "failover"
-    methods:
-      - name: "Online"
-        retries: 0
-      - name: "Offline"
-        retries: 0
-      - name: "Message"
-        retries: 0
-#  "gameConsumer.jumpService":
-#    registry: "demoZk"
-#    protocol: "dubbo"
-#    interface: "org.apache.dubbo.game.JumpService"
-#    cluster: "failover"
-#    methods:
-#      - name: "Online"
-#        retries: 0
-#      - name: "Offline"
-#        retries: 0
-#      - name: "Message"
-#        retries: 0
-
-# protocol config
-protocol_conf:
-  dubbo:
-    reconnect_interval: 0
-    connection_number: 1
-    heartbeat_period: "5s"
-    session_timeout: "180s"
-    pool_size: 64
-    pool_ttl: 600
-    getty_session_param:
-      compress_encoding: false
-      tcp_no_delay: true
-      tcp_keep_alive: true
-      keep_alive_period: "120s"
-      tcp_r_buf_size: 262144
-      tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
-      pkg_wq_size: 512
-      tcp_read_timeout: "1s"
-      tcp_write_timeout: "5s"
-      wait_timeout: "1s"
-      max_msg_len: 1024000
-      session_name: "client"
diff --git a/game/go-server-game/pkg/consumer.go b/game/go-server-game/pkg/consumer.go
old mode 100644
new mode 100755
index 8b66621..a6dba8f
--- a/game/go-server-game/pkg/consumer.go
+++ b/game/go-server-game/pkg/consumer.go
@@ -1,9 +1,7 @@
 package pkg
 
 import (
-	"github.com/apache/dubbo-go-samples/game/pkg/consumer/gate"
+	"github.com/apache/dubbo-go-samples/game/go-server-gate/pkg"
 )
 
-var gateBasketball = new(gate.BasketballService)
-
-// var gateJump = new(gate.JumpService)
+var GateBasketball = new(pkg.BasketballService)
diff --git a/game/go-server-game/pkg/main.go b/game/go-server-game/pkg/main.go
deleted file mode 100644
index ee9baa1..0000000
--- a/game/go-server-game/pkg/main.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package pkg
-
-import (
-	"dubbo.apache.org/dubbo-go/v3/config"
-
-	hessian "github.com/apache/dubbo-go-hessian2"
-)
-
-import (
-	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
-)
-
-func init() {
-	config.SetProviderService(new(BasketballService))
-	// config.SetProviderService(new(JumpService))
-
-	config.SetConsumerService(gateBasketball)
-
-	hessian.RegisterPOJO(&pojo.Result{})
-}
diff --git a/game/go-server-game/pkg/provider.go b/game/go-server-game/pkg/provider.go
old mode 100644
new mode 100755
index 6d2d2ea..b70437b
--- a/game/go-server-game/pkg/provider.go
+++ b/game/go-server-game/pkg/provider.go
@@ -2,6 +2,8 @@ package pkg
 
 import (
 	"context"
+	"fmt"
+	"strconv"
 )
 
 import (
@@ -14,58 +16,95 @@ import (
 
 type BasketballService struct{}
 
-func (p *BasketballService) Online(ctx context.Context, uid string) (*pojo.Result, error) {
-	logger.Infof("online: %s", uid)
-	return &pojo.Result{Code: 0}, nil
+var userMap = make(map[string]*pojo.Info, 0)
+
+func (p *BasketballService) Login(ctx context.Context, uid string) (*pojo.Result, error) {
+    logger.Infof("message: %#v", uid)
+    var (
+        info *pojo.Info
+        ok bool
+    )
+
+    // auto reply the same message
+    rsp, err := GateBasketball.Send(context.TODO(), uid, "")
+    if err != nil {
+        logger.Errorf("send fail: %#s", err.Error())
+        return &pojo.Result{Code: 1, Msg: err.Error()}, err
+    }
+
+    fmt.Println("receive data from gate:", rsp)
+
+    if info, ok = userMap[uid]; !ok {
+        info = &pojo.Info{}
+        info.Name = uid
+        userMap[uid] = info
+    }
+    return &pojo.Result{Code: 0, Msg: info.Name + ", your score is " + strconv.Itoa(info.Score) , Data: map[string]interface{}{"to": uid, "score": info.Score}}, nil
 }
 
-func (p *BasketballService) Offline(ctx context.Context, uid string) (*pojo.Result, error) {
-	logger.Infof("offline: %#s", uid)
-	return &pojo.Result{Code: 0}, nil
+func (p *BasketballService) Score (ctx context.Context, uid, score string) (*pojo.Result, error) {
+    logger.Infof("message: %#v, %#v", uid, score)
+    var (
+        info = &pojo.Info{}
+        ok bool
+    )
+
+    // auto reply the same message
+    rsp, err := GateBasketball.Send(context.TODO(), uid, score)
+    if err != nil {
+        logger.Errorf("send fail: %#s", err.Error())
+        return &pojo.Result{Code: 1, Msg: err.Error()}, err
+    }
+
+    fmt.Println("receive data from gate:", rsp)
+
+    if info, ok = userMap[uid]; !ok {
+      info = &pojo.Info{
+          Name: uid,
+      }
+      userMap[uid] = info
+      logger.Error("user data not found")
+      return &pojo.Result{Code: 1, Msg: "user data not found", Data: map[string]interface{}{}}, nil
+    }
+    intSource, err := strconv.Atoi(score)
+    if err != nil {
+        logger.Error(err.Error())
+    }
+    info.Score += intSource
+
+    return &pojo.Result{Code: 0, Msg: "进球成功", Data: map[string]interface{}{"to": uid, "score": info.Score}}, nil
 }
 
-func (p *BasketballService) Message(ctx context.Context, uid, data string) (*pojo.Result, error) {
-	logger.Infof("message: %#v, %#v", uid, data)
-
-	// // auto reply the same message
-	// _, err := gateBasketball.Send(context.TODO(), uid, data)
-	// if err != nil {
-	//     logger.Errorf("send fail: %#s", err.Error())
-	//     return &pojo.Result{Code: 1, Msg: err.Error()}, err
-	// }
-
-	return &pojo.Result{Code: 0, Data: map[string]interface{}{"to": uid, "message": data}}, nil
+func (p *BasketballService) Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    var (
+        rank = 1
+        info  *pojo.Info
+        ok bool
+    )
+
+    // auto reply the same message
+    rsp, err := GateBasketball.Send(context.TODO(), uid, "")
+    if err != nil {
+        logger.Errorf("send fail: %#s", err.Error())
+        return &pojo.Result{Code: 1, Msg: err.Error()}, err
+    }
+
+    fmt.Println("receive data from gate:", rsp)
+
+    if info, ok = userMap[uid]; !ok {
+        logger.Error("no user found")
+        return &pojo.Result{Code: 1, Msg: "no user found", Data: map[string]interface{}{"to": uid, "rank": rank}}, nil
+    }
+
+    for _, v := range userMap {
+        if v.Score > info.Score {
+            rank ++
+        }
+    }
+
+    return &pojo.Result{Code: 0, Msg: "success", Data: map[string]interface{}{"to": uid, "rank": rank}}, nil
 }
 
 func (p *BasketballService) Reference() string {
-	return "gameProvider.basketballService"
-}
-
-type JumpService struct{}
-
-func (p *JumpService) Online(ctx context.Context, uid string) (*pojo.Result, error) {
-	logger.Infof("online: %#s", uid)
-	return &pojo.Result{Code: 0}, nil
-}
-
-func (p *JumpService) Offline(ctx context.Context, uid string) (*pojo.Result, error) {
-	logger.Infof("offline: %#s", uid)
-	return &pojo.Result{Code: 0}, nil
-}
-
-func (p *JumpService) Message(ctx context.Context, uid, data string) (*pojo.Result, error) {
-	logger.Infof("message: %#s, %#s", uid, data)
-
-	// reply the same message
-	_, err := gateBasketball.Send(context.TODO(), uid, data)
-	if err != nil {
-		logger.Errorf("send fail: %#s", err.Error())
-		return &pojo.Result{Code: 1, Msg: err.Error()}, err
-	}
-
-	return &pojo.Result{Code: 0, Data: map[string]interface{}{"to": uid, "message": data}}, nil
-}
-
-func (p *JumpService) Reference() string {
-	return "gameProvider.jumpService"
+    return "gameProvider.basketballService"
 }
diff --git a/game/go-server-game/tests/integration/gameprovider_test.go b/game/go-server-game/tests/integration/gameprovider_test.go
old mode 100644
new mode 100755
index 659879b..7a8aacf
--- a/game/go-server-game/tests/integration/gameprovider_test.go
+++ b/game/go-server-game/tests/integration/gameprovider_test.go
@@ -10,25 +10,25 @@ import (
 )
 
 func TestMessage(t *testing.T) {
-	res, err := gameProvider.Message(context.TODO(), "A001", "hello")
-	assert.Nil(t, err)
-	assert.NotNil(t, res)
-	assert.Equal(t, int32(0), res.Code)
-	assert.NotNil(t, res.Data)
-	assert.Equal(t, "A001", res.Data["to"])
-	assert.Equal(t, "hello", res.Data["message"])
+    res, err := gameProvider.Login(context.TODO(), "A001")
+    assert.Nil(t, err)
+    assert.NotNil(t, res)
+    assert.Equal(t, int32(0), res.Code)
+    assert.NotNil(t, res.Data)
+    assert.Equal(t, "A001", res.Data["to"])
+    assert.Equal(t, 0, res.Data["score"])
 }
 
 func TestOnline(t *testing.T) {
-	res, err := gameProvider.Online(context.TODO(), "A001")
-	assert.Nil(t, err)
-	assert.NotNil(t, res)
-	assert.Equal(t, int32(0), res.Code)
+    res, err := gameProvider.Score(context.TODO(), "A001", "1")
+    assert.Nil(t, err)
+    assert.NotNil(t, res)
+    assert.Equal(t, int32(0), res.Code)
 }
 
 func TestOffline(t *testing.T) {
-	res, err := gameProvider.Offline(context.TODO(), "A001")
-	assert.Nil(t, err)
-	assert.NotNil(t, res)
-	assert.Equal(t, int32(0), res.Code)
+    res, err := gameProvider.Rank(context.TODO(), "A001")
+    assert.Nil(t, err)
+    assert.NotNil(t, res)
+    assert.Equal(t, int32(0), res.Code)
 }
diff --git a/game/go-server-game/tests/integration/main_test.go b/game/go-server-game/tests/integration/main_test.go
old mode 100644
new mode 100755
index e6b726c..0cd2c5e
--- a/game/go-server-game/tests/integration/main_test.go
+++ b/game/go-server-game/tests/integration/main_test.go
@@ -7,6 +7,7 @@ import (
 )
 
 import (
+	hessian "github.com/apache/dubbo-go-hessian2"
 	_ "dubbo.apache.org/dubbo-go/v3/cluster/cluster_impl"
 	_ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
 	_ "dubbo.apache.org/dubbo-go/v3/common/proxy/proxy_factory"
@@ -16,16 +17,14 @@ import (
 	_ "dubbo.apache.org/dubbo-go/v3/protocol/dubbo"
 	_ "dubbo.apache.org/dubbo-go/v3/registry/protocol"
 	_ "dubbo.apache.org/dubbo-go/v3/registry/zookeeper"
-
-	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
-	"github.com/apache/dubbo-go-samples/game/pkg/consumer/game"
+	"github.com/apache/dubbo-go-samples/game/go-server-game/pkg"
 	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
 )
 
-var gameProvider = new(game.BasketballService)
+var gameProvider = new(pkg.BasketballService)
 
 func TestMain(m *testing.M) {
 	config.SetConsumerService(gameProvider)
diff --git a/game/go-server-gate/cmd/server.go b/game/go-server-gate/cmd/server.go
old mode 100644
new mode 100755
index 3ba70ec..eedcc1b
--- a/game/go-server-gate/cmd/server.go
+++ b/game/go-server-gate/cmd/server.go
@@ -3,14 +3,17 @@ package main
 import (
 	"context"
 	"encoding/json"
+	"io/ioutil"
 	"net/http"
 	"os"
 	"os/signal"
+	"strconv"
 	"syscall"
 	"time"
 )
 
 import (
+	hessian "github.com/apache/dubbo-go-hessian2"
 	_ "dubbo.apache.org/dubbo-go/v3/cluster/cluster_impl"
 	_ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
 	"dubbo.apache.org/dubbo-go/v3/common/logger"
@@ -25,8 +28,18 @@ import (
 
 import (
 	"github.com/apache/dubbo-go-samples/game/go-server-gate/pkg"
+	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
 )
 
+func init() {
+    config.SetProviderService(new(pkg.BasketballService))
+
+    config.SetConsumerService(pkg.GameBasketball)
+
+    hessian.RegisterPOJO(&pojo.Result{})
+}
+
+
 func main() {
 	config.Load()
 
@@ -59,21 +72,68 @@ func initSignal() {
 }
 
 func startHttp() {
-	http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
-		res, err := pkg.Message(context.TODO(), "abc", "hello")
-		if err != nil {
-			_, _ = w.Write([]byte(err.Error()))
-			return
-		}
 
-		b, err := json.Marshal(res)
-		if err != nil {
-			_, _ = w.Write([]byte(err.Error()))
-			return
-		}
+    http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
+        res, err := pkg.Login(context.TODO(), r.URL.Query().Get("name"))
+        if err != nil {
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
+            return
+        }
+
+        b, err := json.Marshal(res)
+        if err != nil {
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
+            return
+        }
+        responseWithOrigin(w, r, 200, b)
+    })
+
+    http.HandleFunc("/score", func(w http.ResponseWriter, r *http.Request) {
+        reqBody, err := ioutil.ReadAll(r.Body)
+        if err != nil {
+            logger.Error(err.Error())
+        }
+        var info pojo.Info
+        json.Unmarshal(reqBody, &info)
+        res, err := pkg.Score(context.TODO(), info.Name, strconv.Itoa(info.Score))
+        if err != nil {
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
+            return
+        }
 
-		_, _ = w.Write(b)
-	})
+        b, err := json.Marshal(res)
+        if err != nil {
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
+            return
+        }
+        responseWithOrigin(w, r, 200, b)
+    })
+
+    http.HandleFunc("/rank", func(w http.ResponseWriter, r *http.Request) {
+        res, err := pkg.Rank(context.TODO(), r.URL.Query().Get("name"))
+        if err != nil {
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
+            return
+        }
+        b, err := json.Marshal(res)
+        if err != nil {
+            responseWithOrigin(w, r, 200, []byte(err.Error()))
+            return
+        }
+        responseWithOrigin(w, r, 200, b)
+    })
+
+    _ = http.ListenAndServe("127.0.0.1:8089", nil)
+}
 
-	_ = http.ListenAndServe(":8000", nil)
+// avoid cors
+func responseWithOrigin(w http.ResponseWriter, r *http.Request, code int, json []byte) {
+    w.Header().Set("Access-Control-Allow-Origin", "*")
+    w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
+    w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
+    w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
+    w.Header().Set("Access-Control-Allow-Credentials", "true")
+    w.Header().Set("Content-Type", "application/json; charset=utf-8")
+    w.WriteHeader(code)
+    w.Write(json)
 }
diff --git a/game/go-server-gate/conf/test_client.yml b/game/go-server-gate/conf/test_client.yml
deleted file mode 100644
index d834ac9..0000000
--- a/game/go-server-gate/conf/test_client.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-# dubbo client yaml configure file
-
-check: false
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application:
-  organization : "dubbo.io"
-  name  : "GateServiceTest"
-  module : "dubbo-go gate service client"
-  version : "0.0.1"
-  environment : "dev"
-
-# registry config
-registries :
-  "demoZk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2181"
-    username: ""
-    password: ""
-
-# reference config
-references:
-  "gateConsumer.basketballService":
-    registry: "demoZk"
-    protocol : "dubbo"
-    interface : "org.apache.dubbo.gate.BasketballService"
-    cluster: "failover"
-    methods:
-      - name: "Send"
-        retries: 0
-#  "gateConsumer.jumpService":
-#    registry: "demoZk"
-#    protocol: "dubbo"
-#    interface: "org.apache.dubbo.gate.JumpService"
-#    cluster: "failover"
-#    methods:
-#      - name: "Send"
-#        retries: 0
-
-# protocol config
-protocol_conf:
-  dubbo:
-    reconnect_interval: 0
-    connection_number: 1
-    heartbeat_period: "5s"
-    session_timeout: "180s"
-    pool_size: 64
-    pool_ttl: 600
-    getty_session_param:
-      compress_encoding: false
-      tcp_no_delay: true
-      tcp_keep_alive: true
-      keep_alive_period: "120s"
-      tcp_r_buf_size: 262144
-      tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
-      pkg_wq_size: 512
-      tcp_read_timeout: "1s"
-      tcp_write_timeout: "5s"
-      wait_timeout: "1s"
-      max_msg_len: 1024000
-      session_name: "client"
diff --git a/game/go-server-gate/pkg/consumer.go b/game/go-server-gate/pkg/consumer.go
old mode 100644
new mode 100755
index 3ccafd7..3709d96
--- a/game/go-server-gate/pkg/consumer.go
+++ b/game/go-server-gate/pkg/consumer.go
@@ -9,23 +9,20 @@ import (
 	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
 )
 
-var gameBasketball = new(game.BasketballService)
+var GameBasketball = new(game.BasketballService)
 
 // var gameJump = new(game.JumpService)
 
 // just easy for demo test
 
-func Message(ctx context.Context, uid string, data string) (*pojo.Result, error) {
-	return gameBasketball.Message(ctx, uid, data)
-	// return gameJump.Message(ctx, uid, data)
+func Login(ctx context.Context, data string) (*pojo.Result, error) {
+    return GameBasketball.Login(ctx, data)
 }
 
-func Online(ctx context.Context, uid string) (*pojo.Result, error) {
-	return gameBasketball.Online(ctx, uid)
-	// return gameJump.Online(ctx, uid)
+func Score(ctx context.Context, uid, score string) (*pojo.Result, error) {
+    return GameBasketball.Score(ctx, uid, score)
 }
 
-func Offline(ctx context.Context, uid string) (*pojo.Result, error) {
-	return gameBasketball.Offline(ctx, uid)
-	// return gameJump.Offline(ctx, uid)
+func Rank (ctx context.Context, uid string) (*pojo.Result, error) {
+    return GameBasketball.Rank(ctx, uid)
 }
diff --git a/game/go-server-gate/pkg/main.go b/game/go-server-gate/pkg/main.go
deleted file mode 100644
index 6f3a7b0..0000000
--- a/game/go-server-gate/pkg/main.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package pkg
-
-import (
-	"dubbo.apache.org/dubbo-go/v3/config"
-
-	hessian "github.com/apache/dubbo-go-hessian2"
-)
-
-import (
-	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
-)
-
-func init() {
-	config.SetProviderService(new(BasketballService))
-	// config.SetProviderService(new(JumpService))
-
-	config.SetConsumerService(gameBasketball)
-
-	hessian.RegisterPOJO(&pojo.Result{})
-}
diff --git a/game/go-server-gate/pkg/provider.go b/game/go-server-gate/pkg/provider.go
old mode 100644
new mode 100755
index 257da4d..0ba36b7
--- a/game/go-server-gate/pkg/provider.go
+++ b/game/go-server-gate/pkg/provider.go
@@ -22,14 +22,3 @@ func (p *BasketballService) Send(ctx context.Context, uid, data string) (*pojo.R
 func (p *BasketballService) Reference() string {
 	return "gateProvider.basketballService"
 }
-
-type JumpService struct{}
-
-func (p *JumpService) Send(ctx context.Context, uid, data string) (*pojo.Result, error) {
-	logger.Infof("jump: to=%s, message=%s", uid, data)
-	return &pojo.Result{Code: 0, Data: map[string]interface{}{"to": uid, "message": data}}, nil
-}
-
-func (p *JumpService) Reference() string {
-	return "gateProvider.jumpService"
-}
diff --git a/game/go-server-gate/tests/integration/gateprovider_test.go b/game/go-server-gate/tests/integration/gateprovider_test.go
old mode 100644
new mode 100755
diff --git a/game/go-server-gate/tests/integration/main_test.go b/game/go-server-gate/tests/integration/main_test.go
old mode 100644
new mode 100755
index 3797af0..ae2ddf5
--- a/game/go-server-gate/tests/integration/main_test.go
+++ b/game/go-server-gate/tests/integration/main_test.go
@@ -21,11 +21,11 @@ import (
 )
 
 import (
-	"github.com/apache/dubbo-go-samples/game/pkg/consumer/gate"
+	"github.com/apache/dubbo-go-samples/game/go-server-gate/pkg"
 	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
 )
 
-var gateProvider = new(gate.BasketballService)
+var gateProvider = new(pkg.BasketballService)
 
 func TestMain(m *testing.M) {
 	config.SetConsumerService(gateProvider)
diff --git a/game/pkg/consumer/game/basketball.go b/game/pkg/consumer/game/basketball.go
old mode 100644
new mode 100755
index e4bd94f..c244f7d
--- a/game/pkg/consumer/game/basketball.go
+++ b/game/pkg/consumer/game/basketball.go
@@ -9,9 +9,9 @@ import (
 )
 
 type BasketballService struct {
-	Online  func(ctx context.Context, uid string) (*pojo.Result, error)
-	Offline func(ctx context.Context, uid string) (*pojo.Result, error)
-	Message func(ctx context.Context, uid string, data string) (*pojo.Result, error)
+    Login   func(ctx context.Context, uid string) (*pojo.Result, error)
+    Score   func(ctx context.Context, uid, score string) (*pojo.Result, error)
+    Rank  func(ctx context.Context, uid string) (*pojo.Result, error)
 }
 
 func (p *BasketballService) Reference() string {
diff --git a/game/pkg/consumer/game/jump.go b/game/pkg/consumer/game/jump.go
deleted file mode 100644
index 0b24bc4..0000000
--- a/game/pkg/consumer/game/jump.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package game
-
-import (
-	"context"
-)
-
-import (
-	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
-)
-
-type JumpService struct {
-	Online  func(ctx context.Context, uid string) (*pojo.Result, error)
-	Offline func(ctx context.Context, uid string) (*pojo.Result, error)
-	Message func(ctx context.Context, uid string, data string) (*pojo.Result, error)
-}
-
-func (p *JumpService) Reference() string {
-	return "gameConsumer.jumpService"
-}
diff --git a/game/pkg/consumer/gate/basketball.go b/game/pkg/consumer/gate/basketball.go
old mode 100644
new mode 100755
diff --git a/game/pkg/consumer/gate/jump.go b/game/pkg/consumer/gate/jump.go
deleted file mode 100644
index d9587b3..0000000
--- a/game/pkg/consumer/gate/jump.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package gate
-
-import (
-	"context"
-)
-
-import (
-	"github.com/apache/dubbo-go-samples/game/pkg/pojo"
-)
-
-type JumpService struct {
-	Send func(ctx context.Context, uid string, data string) (*pojo.Result, error)
-}
-
-func (p *JumpService) Reference() string {
-	return "gateConsumer.jumpService"
-}
diff --git a/game/pkg/pojo/info.go b/game/pkg/pojo/info.go
new file mode 100755
index 0000000..6125b5a
--- /dev/null
+++ b/game/pkg/pojo/info.go
@@ -0,0 +1,10 @@
+package pojo
+
+type Info struct {
+	Name string `json:"name"`
+	Score int	`json:"score"`
+}
+
+func (m Info) JavaClassName() string {
+	return "org.apache.dubbo.pojo.Info"
+}
diff --git a/game/website/css/style.css b/game/website/css/style.css
new file mode 100755
index 0000000..5f21f5a
--- /dev/null
+++ b/game/website/css/style.css
@@ -0,0 +1,54 @@
+*{
+    margin: 0;
+    padding: 0;
+}
+#myProgress {
+    width: 100%;
+    background-color: #ddd;
+}
+#myBar {
+    width: 0%;
+    height: 30px;
+    background-color: #4CAF50;
+    text-align: center;
+    line-height: 30px;
+    color: white;
+}
+.background{
+    background-image: url('../img/bac.png');
+    position: absolute;
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    width: 100%;
+    height:100%;
+}
+.gate{
+    width:8rem;
+    height: 4rem;
+    top: 5%;
+    left: 50%;
+    margin-left: -4rem;
+    position: absolute;
+}
+.ball{
+    width: 3rem;
+    height: 3rem;
+    bottom: 0;
+    left: 50%;
+    margin-left: -2.5rem;
+    position: absolute;
+}
+.people{
+    width: 5rem;
+    height: 10rem;
+    bottom: 0;
+    left: 50%;
+    margin-left: -2.5rem;
+    position: absolute;
+}
+.info{
+    position: absolute;
+    top: 10px;
+    left: 10px;
+    color: white;
+}
\ No newline at end of file
diff --git a/game/website/img/bac.png b/game/website/img/bac.png
new file mode 100755
index 0000000..f6dc266
Binary files /dev/null and b/game/website/img/bac.png differ
diff --git a/game/website/index.html b/game/website/index.html
new file mode 100755
index 0000000..a3554db
--- /dev/null
+++ b/game/website/index.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>FootBall Game</title>
+    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
+    <!-- import Vue before Element -->
+    <script src="https://unpkg.com/vue/dist/vue.js"></script>
+    <!-- 引入样式 -->
+    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
+    <link rel="stylesheet" href="css/style.css">
+    <!-- 引入组件库 -->
+    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
+
+</head>
+
+<body>
+    <div id="app" class="background">
+        <div id="myProgress">
+            <div id="myBar">0%</div>
+        </div>
+        <div class="info" v-if="!dialogVisible">
+            用户:{{info.name}}
+            <br>
+            分数:{{info.score}}
+            <br>
+            排名:{{info.rank}}
+        </div>
+        <svg id="gate" class="gate" t="1620527545136" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2966" width="400" height="400"><path d="M861.414041 192.806237 179.968861 192.806237c-51.828412 0-93.985558 42.164309-93.985558 93.985558l0 514.915399 61.975517 0 0-0.276293 0.796132 0.650823 74.704422-89.905636 597.571934 0 72.39482 87.839581 0 1.691525 62.007239 0L955.433368 286.791795C955.432345 234.970546 913.228127 192.806237 861.414041 19 [...]
+        <svg id="ball" class="ball" t="1620527208144" class="icon" viewBox="0 0 1365 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1801" width="400" height="400"><path d="M647.937 1023.573c-40.96 0-82.133-5.12-122.24-14.933-66.773-16.427-128.427-45.44-183.04-86.4-52.693-39.467-96.853-88.107-131.2-144.853-34.347-56.747-56.96-118.4-67.2-183.467-10.88-67.413-7.893-135.467 8.533-202.24 14.08-56.747 37.334-110.293 69.12-158.72 30.934-46.72 69.12-88.107 113.707-122.453 44.16-34. [...]
+        <svg class="people" @click="clickPeople" t="1620527325090" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2618" width="400" height="400"><path d="M563.240423 102.320551m-102.320551 0a102.320551 102.320551 0 1 0 204.641102 0 102.320551 102.320551 0 1 0-204.641102 0Z" p-id="2619" fill="#e6e6e6"></path><path d="M322.895467 827.809372c-8.907907 20.054828-155.767992 195.805422-155.767992 195.805421h122.447605s106.292996-119.58263 113.924906 [...]
+        <el-dialog
+        title="输入姓名"
+        :visible="dialogVisible"
+        width="30%"
+        :show-close="false"
+        >
+        <el-form v-model="info">
+            <el-form-item label="姓名">
+                <el-input v-model="info.name"></el-input>
+            </el-form-item>
+        </el-form>
+        <span slot="footer" class="dialog-footer">
+            <el-button type="primary" @click="submitInfo">确 定</el-button>
+        </span>
+        </el-dialog>
+    </div>
+    <script src="js/api.js"></script>
+    <script src="js/index.js"></script>
+    
+</body>
+
+</html>
\ No newline at end of file
diff --git a/game/website/js/api.js b/game/website/js/api.js
new file mode 100755
index 0000000..32a2358
--- /dev/null
+++ b/game/website/js/api.js
@@ -0,0 +1,64 @@
+var baseURL = 'http://127.0.0.1:8089/'
+
+function login(data) {
+    return new Promise(function(resolve, reject) {
+        $.ajax({
+            type: "get",
+            url: baseURL + 'login',
+            data:data,
+            dataType: "json", //指定服务器返回的数据类型
+            success: function (response) {
+                if (response.code != 0) {
+                    reject(response.msg)
+                } else {
+                    resolve(response)
+                }
+            },
+            error:function(err){
+                reject(err)
+            }
+        });
+    })
+}
+
+function score(data) {
+    return new Promise(function(resolve, reject) {
+        $.ajax({
+            type: "post",
+            url: baseURL + 'score',
+            data:data,
+            dataType: "json", //指定服务器返回的数据类型
+            success: function (response) {
+                if (response.code != 0) {
+                    reject(response.msg)
+                } else {
+                    resolve(response)
+                }
+            },
+            error:function(err){
+                reject(err)
+            }
+        })
+    })
+}
+
+function rank(data) {
+    return new Promise(function(resolve, reject) {
+        $.ajax({
+            type: "get",
+            url: baseURL + 'rank',
+            data:data,
+            dataType: "json", //指定服务器返回的数据类型
+            success: function (response) {
+                if (response.code != 0) {
+                    reject(response.msg)
+                } else {
+                    resolve(response)
+                }
+            },
+            error:function(err){
+                reject(err)
+            }
+        })
+    })
+}
\ No newline at end of file
diff --git a/game/website/js/index.js b/game/website/js/index.js
new file mode 100755
index 0000000..7e9be35
--- /dev/null
+++ b/game/website/js/index.js
@@ -0,0 +1,130 @@
+new Vue({
+    el: '#app',
+    data: function () {
+        return { 
+            visible: false,
+            dialogVisible:true,
+            info:{
+                name:'',
+                score:0,
+                rank:0
+            },
+            isMeet:false
+        }
+    },
+    computed:{
+        clientHeight:function(){
+            return document.documentElement.clientWidth
+        },
+        gateHeight:function(){
+            var self = document.getElementById("gate");
+            return self.getBoundingClientRect().top + document.documentElement.scrollTop
+        },
+        geteLeft:function(){
+            var self = document.getElementById("gate");
+            return self.getBoundingClientRect().left
+        }
+    },
+    methods: {
+        getRank:function(){
+            rank({name: this.info.name}).then(Response => {
+                this.info.rank = Response.data.rank
+            }).catch(e => {
+                this.$message({
+                    message: "获取排名失败" + e,
+                    type:"danger"
+                })
+            })
+        },
+        submitInfo:function(){
+            this.dialogVisible = false
+            login({name: this.info.name}).then(Response => {
+                this.info.name = Response.data.to
+                this.$message({
+                    message:"欢迎" + Response.msg
+                })
+                this.getRank()
+            }).catch(e => {
+                this.$message({
+                    message: "登陆失败" + e,
+                    type:"danger"
+                })
+            })
+        },
+        moveBall:function(){
+            var elem = document.getElementsByClassName("ball")
+            var gate = document.getElementById("gate")
+            var id = setInterval(frame, 20)
+            var tempHeight = 0
+            var that = this
+            function frame() {
+                var space = elem[0].getBoundingClientRect().left - gate.getBoundingClientRect().left
+                var hight = elem[0].getBoundingClientRect().top - gate.getBoundingClientRect().top
+                if (!that.isMeet && (space <60 && space > -20 && hight < 20 && hight > -20)) {
+                    that.isMeet = true
+                    score(JSON.stringify({name:that.info.name, score:1})).then(Response => {
+                        that.info.score = Response.data.score
+                        that.$message({
+                            message:"进球成功, 总分数为:" + Response.data.score,
+                            type:"success"
+                        })
+                        that.getRank()
+                    }).catch( e => {
+                        that.$message({
+                            message: "分数统计失败" + e,
+                            type:"danger"
+                        })
+                    })
+                }
+                if (tempHeight >= that.clientHeight) {
+                    elem[0].style.bottom = 0 + ''
+                    clearInterval(id)
+                } else{
+                    tempHeight += 20
+                    elem[0].style.bottom = tempHeight + ''
+                }
+            }
+        },
+        move: function () {
+            var elem = document.getElementById("myBar")
+            var width = 0
+            var id = setInterval(frame, 20)
+            function frame() {
+                if (width >= 100) {
+                    clearInterval(id)
+                    elem.remove()
+                } else {
+                    width++
+                    elem.style.width = width + '%'
+                    elem.innerHTML = width * 1 + '%'
+                }
+            }
+            
+        },
+        moveGate:function(){
+            var elem = document.getElementById("gate")
+            var id = setInterval(frame, 20)
+            var model = false
+            var tempValue = 0
+            var increase = 1
+            function frame() {
+                if (tempValue > 100 || tempValue < -100) {
+                    increase = -increase
+                }
+                tempValue += increase
+                elem.style.marginLeft = tempValue + 'px'
+            }
+        },
+        clickPeople(){
+            this.isMeet = false
+            this.moveBall()
+        }
+    },
+    mounted(){
+        this.move()
+        this.moveGate()
+    },
+    created() {
+        
+    }
+})
\ No newline at end of file
diff --git a/start_integrate_test.sh b/start_integrate_test.sh
index 881d7af..89a50bc 100755
--- a/start_integrate_test.sh
+++ b/start_integrate_test.sh
@@ -38,6 +38,10 @@ array+=("filter/custom/go-server")
 array+=("filter/tpslimit/go-server")
 array+=("filter/sentinel/go-server")
 
+# game
+array+=("game/go-server-game")
+array+=("game/go-server-gate")
+
 # general-dubbo
 array+=("general/dubbo/go-server")