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

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


The following commit(s) were added to refs/heads/master by this push:
     new b83754b  Ftr: game sample for master (#267)
b83754b is described below

commit b83754bc7890864eaf89b0a242606b213baf613c
Author: 氕氘氚 <[email protected]>
AuthorDate: Sun Oct 3 16:11:00 2021 +0800

    Ftr: game sample for master (#267)
    
    * feat: add game sample
    
    * feat: add game sample
    
    * feat: add apache license
    
    * fix: integrate_test path error
    
    * fix: delete new, delete 0 in make
---
 .run/game-go-game.run.xml                          |  14 ++
 .run/game-go-gate.run.xml                          |  14 ++
 game/go-server-game/cmd/consumer.go                |  22 +++
 game/go-server-game/cmd/provider.go                | 127 ++++++++++++++++++
 game/go-server-game/cmd/server.go                  |  73 ++++++++++
 game/go-server-game/conf/dubbogo.yml               |  54 ++++++++
 game/go-server-gate/cmd/consumer.go                |  43 ++++++
 game/go-server-gate/cmd/provider.go                |  41 ++++++
 game/go-server-gate/cmd/server.go                  | 147 +++++++++++++++++++++
 game/go-server-gate/conf/dubbogo.yml               |  56 ++++++++
 game/pkg/consumer/game/basketball.go               |  36 +++++
 game/pkg/consumer/gate/basketball.go               |  34 +++++
 game/pkg/pojo/info.go                              |  27 ++++
 game/pkg/pojo/result.go                            |  32 +++++
 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 ++++++++++++++++++
 .../go-server-game/tests/integration/main_test.go  |  47 +++++++
 .../tests/integration/provider_test.go             |  51 +++++++
 .../go-server-gate/tests/integration/main_test.go  |  47 +++++++
 .../tests/integration/provider_test.go             |  37 ++++++
 start_integrate_test.sh                            |   4 +
 24 files changed, 1210 insertions(+)

diff --git a/.run/game-go-game.run.xml b/.run/game-go-game.run.xml
new file mode 100644
index 0000000..6c0a041
--- /dev/null
+++ b/.run/game-go-game.run.xml
@@ -0,0 +1,14 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="game-go-game" 
type="GoApplicationRunConfiguration" factoryName="Go Application">
+    <module name="dubbo-go-samples" />
+    <working_directory value="$PROJECT_DIR$" />
+    <envs>
+      <env name="DUBBO_GO_CONFIG_PATH" 
value="$PROJECT_DIR$/game/go-server-game/conf/dubbogo.yml" />
+    </envs>
+    <kind value="PACKAGE" />
+    <package 
value="github.com/apache/dubbo-go-samples/game/go-server-game/cmd" />
+    <directory value="$PROJECT_DIR$" />
+    <filePath value="$PROJECT_DIR$/game/go-server-game/cmd/server.go" />
+    <method v="2" />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/.run/game-go-gate.run.xml b/.run/game-go-gate.run.xml
new file mode 100644
index 0000000..6da7cc2
--- /dev/null
+++ b/.run/game-go-gate.run.xml
@@ -0,0 +1,14 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="game-go-gate" 
type="GoApplicationRunConfiguration" factoryName="Go Application">
+    <module name="dubbo-go-samples" />
+    <working_directory value="$PROJECT_DIR$" />
+    <envs>
+      <env name="DUBBO_GO_CONFIG_PATH" 
value="$PROJECT_DIR$/game/go-server-gate/conf/dubbogo.yml" />
+    </envs>
+    <kind value="PACKAGE" />
+    <package 
value="github.com/apache/dubbo-go-samples/game/go-server-gate/cmd" />
+    <directory value="$PROJECT_DIR$" />
+    <filePath value="$PROJECT_DIR$/game/go-server-gate/cmd/server.go" />
+    <method v="2" />
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/game/go-server-game/cmd/consumer.go 
b/game/go-server-game/cmd/consumer.go
new file mode 100644
index 0000000..9581b49
--- /dev/null
+++ b/game/go-server-game/cmd/consumer.go
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import "github.com/apache/dubbo-go-samples/game/pkg/consumer/gate"
+
+var GateBasketball = gate.BasketballService{}
diff --git a/game/go-server-game/cmd/provider.go 
b/game/go-server-game/cmd/provider.go
new file mode 100644
index 0000000..489e083
--- /dev/null
+++ b/game/go-server-game/cmd/provider.go
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+       "fmt"
+       "strconv"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/logger"
+)
+
+import (
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+type BasketballService struct{}
+
+var userMap = make(map[string]*pojo.Info)
+
+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) 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) 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"
+}
diff --git a/game/go-server-game/cmd/server.go 
b/game/go-server-game/cmd/server.go
new file mode 100644
index 0000000..90b05fc
--- /dev/null
+++ b/game/go-server-game/cmd/server.go
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "os"
+       "os/signal"
+       "syscall"
+       "time"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/logger"
+       "dubbo.apache.org/dubbo-go/v3/config"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+func init() {
+       config.SetProviderService(new(BasketballService))
+
+       config.SetConsumerService(GateBasketball)
+
+       hessian.RegisterPOJO(&pojo.Result{})
+}
+
+func main() {
+       config.Load()
+
+       initSignal()
+}
+
+func initSignal() {
+       signals := make(chan os.Signal, 1)
+
+       signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP, 
syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
+       for {
+               sig := <-signals
+               logger.Infof("get signal %#s", sig.String())
+               switch sig {
+               case syscall.SIGHUP:
+                       logger.Infof("app need reload")
+               default:
+                       time.AfterFunc(time.Duration(time.Second*5), func() {
+                               logger.Warnf("app exit now by force...")
+                               os.Exit(1)
+                       })
+
+                       // The program exits normally or timeout forcibly exits.
+                       logger.Warnf("app exit now...")
+                       return
+               }
+       }
+}
diff --git a/game/go-server-game/conf/dubbogo.yml 
b/game/go-server-game/conf/dubbogo.yml
new file mode 100644
index 0000000..0d9b8cd
--- /dev/null
+++ b/game/go-server-game/conf/dubbogo.yml
@@ -0,0 +1,54 @@
+dubbo:
+  registries:
+    demoZK:
+      protocol: zookeeper
+      timeout: 3s
+      address: 127.0.0.1:2181
+  consumer:
+    registry:
+      - demoZK
+    references:
+      gateConsumer.basketballService:
+        protocol: dubbo
+        interface: org.apache.dubbo.gate.basketballService
+        cluster: "failover"
+        methods:
+          - name: "Send"
+            retries: 0
+  provider:
+    registry:
+      - demoZK
+    services:
+      gameProvider.basketballService:
+        protocol: dubbo
+        interface: org.apache.dubbo.game.basketballService # must be 
compatible with grpc or dubbo-java
+        loadbalance: "random"
+        warmup: "100"
+        cluster: "failover"
+        methods:
+          - name: "Online"
+            retries: 0
+          - name: "Offline"
+            retries: 0
+          - name: "Message"
+            retries: 0
+  protocols:
+    dubbo:
+      name: dubbo
+      port: 20000
+      # 在 params 中定义当前使用的协议特有的网络配置
+      # 如该 sample 配置的是 dubbo 协议(底层使用 getty 通信库)
+      params:
+        session-number: 700
+        session-timeout: 180s
+        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
+        tcp-read-timeout: 10s
+        tcp-write-timeout: 5s
+        wait-timeout: 1s
+        max-msg-len: 1024000
+        session-name: server
\ No newline at end of file
diff --git a/game/go-server-gate/cmd/consumer.go 
b/game/go-server-gate/cmd/consumer.go
new file mode 100644
index 0000000..a7cffa9
--- /dev/null
+++ b/game/go-server-gate/cmd/consumer.go
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+)
+
+import (
+       "github.com/apache/dubbo-go-samples/game/pkg/consumer/game"
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+var GameBasketball = game.BasketballService{}
+
+// just easy for demo test
+
+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)
+}
diff --git a/game/go-server-gate/cmd/provider.go 
b/game/go-server-gate/cmd/provider.go
new file mode 100644
index 0000000..8dac483
--- /dev/null
+++ b/game/go-server-gate/cmd/provider.go
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/logger"
+)
+
+import (
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+type BasketballService struct{}
+
+func (p *BasketballService) Send(ctx context.Context, uid, data string) 
(*pojo.Result, error) {
+       logger.Infof("basketball: to=%s, message=%s", uid, data)
+       return &pojo.Result{Code: 0, Data: map[string]interface{}{"to": uid, 
"message": data}}, nil
+}
+
+func (p *BasketballService) Reference() string {
+       return "gateProvider.basketballService"
+}
diff --git a/game/go-server-gate/cmd/server.go 
b/game/go-server-gate/cmd/server.go
new file mode 100644
index 0000000..6697c85
--- /dev/null
+++ b/game/go-server-gate/cmd/server.go
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "context"
+       "encoding/json"
+       "io/ioutil"
+       "net/http"
+       "os"
+       "os/signal"
+       "strconv"
+       "syscall"
+       "time"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/logger"
+       "dubbo.apache.org/dubbo-go/v3/config"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+func init() {
+       config.SetProviderService(new(BasketballService))
+
+       config.SetConsumerService(GameBasketball)
+
+       hessian.RegisterPOJO(&pojo.Result{})
+}
+
+func main() {
+       config.Load()
+
+       go startHttp()
+
+       initSignal()
+}
+
+func initSignal() {
+       signals := make(chan os.Signal, 1)
+
+       signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP, 
syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
+       for {
+               sig := <-signals
+               logger.Infof("get signal %s", sig.String())
+               switch sig {
+               case syscall.SIGHUP:
+                       logger.Infof("app need reload")
+               default:
+                       time.AfterFunc(time.Duration(time.Second*5), func() {
+                               logger.Warnf("app exit now by force...")
+                               os.Exit(1)
+                       })
+
+                       // The program exits normally or timeout forcibly exits.
+                       logger.Warnf("app exit now...")
+                       return
+               }
+       }
+}
+
+func startHttp() {
+
+       http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
+               res, err := 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 := Score(context.TODO(), info.Name, 
strconv.Itoa(info.Score))
+               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("/rank", func(w http.ResponseWriter, r *http.Request) {
+               res, err := 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)
+}
+
+// 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/dubbogo.yml 
b/game/go-server-gate/conf/dubbogo.yml
new file mode 100644
index 0000000..e9dfb0c
--- /dev/null
+++ b/game/go-server-gate/conf/dubbogo.yml
@@ -0,0 +1,56 @@
+dubbo:
+  registries:
+    demoZK:
+      protocol: zookeeper
+      timeout: 3s
+      address: 127.0.0.1:2181
+  consumer:
+    registry:
+      - demoZK
+    references:
+      gameConsumer.basketballService:
+        protocol: dubbo
+        interface: org.apache.dubbo.game.basketballService
+        cluster: "failover"
+        registry:
+          - demoZK
+        methods:
+          - name: "Online"
+            retries: 0
+          - name: "Offline"
+            retries: 0
+          - name: "Message"
+            retries: 0
+  provider:
+    registry:
+      - demoZK
+    services:
+      gateProvider.basketballService:
+        protocol: dubbo
+        interface: org.apache.dubbo.gate.basketballService # must be 
compatible with grpc or dubbo-java
+        loadbalance: "random"
+        warmup: "100"
+        cluster: "failover"
+        methods:
+          - name: "Send"
+            retries: 0
+  protocols:
+    dubbo:
+      name: dubbo
+      port: 20001
+      # 在 params 中定义当前使用的协议特有的网络配置
+      # 如该 sample 配置的是 dubbo 协议(底层使用 getty 通信库)
+      params:
+        session-number: 700
+        session-timeout: 180s
+        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
+        tcp-read-timeout: 10s
+        tcp-write-timeout: 5s
+        wait-timeout: 1s
+        max-msg-len: 1024000
+        session-name: server
\ No newline at end of file
diff --git a/game/pkg/consumer/game/basketball.go 
b/game/pkg/consumer/game/basketball.go
new file mode 100644
index 0000000..67a23c1
--- /dev/null
+++ b/game/pkg/consumer/game/basketball.go
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package game
+
+import (
+       "context"
+)
+
+import (
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+type BasketballService struct {
+       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 {
+       return "gameConsumer.basketballService"
+}
diff --git a/game/pkg/consumer/gate/basketball.go 
b/game/pkg/consumer/gate/basketball.go
new file mode 100644
index 0000000..c596c20
--- /dev/null
+++ b/game/pkg/consumer/gate/basketball.go
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package gate
+
+import (
+       "context"
+)
+
+import (
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+type BasketballService struct {
+       Send func(ctx context.Context, uid string, data string) (*pojo.Result, 
error)
+}
+
+func (p *BasketballService) Reference() string {
+       return "gateConsumer.basketballService"
+}
diff --git a/game/pkg/pojo/info.go b/game/pkg/pojo/info.go
new file mode 100644
index 0000000..dcb2931
--- /dev/null
+++ b/game/pkg/pojo/info.go
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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/pkg/pojo/result.go b/game/pkg/pojo/result.go
new file mode 100644
index 0000000..b161860
--- /dev/null
+++ b/game/pkg/pojo/result.go
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package pojo
+
+type Result struct {
+       Code int32                  `json:"code"` // 0: success, [1, *): error
+       Msg  string                 `json:"msg,omitempty"`
+       Data map[string]interface{} `json:"data,omitempty"`
+}
+
+func (m Result) JavaClassName() string {
+       return "org.apache.dubbo.pojo.Result"
+}
+
+func (m *Result) Success() bool {
+       return m.Code == 0
+}
diff --git a/game/website/css/style.css b/game/website/css/style.css
new file mode 100644
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 100644
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 100644
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 100644
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 100644
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/integrate_test/game/go-server-game/tests/integration/main_test.go 
b/integrate_test/game/go-server-game/tests/integration/main_test.go
new file mode 100644
index 0000000..0cc0613
--- /dev/null
+++ b/integrate_test/game/go-server-game/tests/integration/main_test.go
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package integration
+
+import (
+       "os"
+       "testing"
+       "time"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/config"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+       game "github.com/apache/dubbo-go-samples/game/go-server-game/cmd"
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+var gameProvider = game.BasketballService{}
+
+func TestMain(m *testing.M) {
+       config.SetConsumerService(gameProvider)
+
+       hessian.RegisterPOJO(&pojo.Result{})
+       config.Load()
+       time.Sleep(3 * time.Second)
+
+       os.Exit(m.Run())
+}
diff --git 
a/integrate_test/game/go-server-game/tests/integration/provider_test.go 
b/integrate_test/game/go-server-game/tests/integration/provider_test.go
new file mode 100644
index 0000000..2d1774a
--- /dev/null
+++ b/integrate_test/game/go-server-game/tests/integration/provider_test.go
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package integration
+
+import (
+       "context"
+       "testing"
+)
+
+import (
+       "github.com/stretchr/testify/assert"
+)
+
+func TestLogin(t *testing.T) {
+       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 TestScore(t *testing.T) {
+       res, err := gameProvider.Score(context.TODO(), "A001", "1")
+       assert.Nil(t, err)
+       assert.NotNil(t, res)
+       assert.Equal(t, int32(0), res.Code)
+}
+
+func TestRank(t *testing.T) {
+       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/integrate_test/game/go-server-gate/tests/integration/main_test.go 
b/integrate_test/game/go-server-gate/tests/integration/main_test.go
new file mode 100644
index 0000000..8f34a3b
--- /dev/null
+++ b/integrate_test/game/go-server-gate/tests/integration/main_test.go
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package integration
+
+import (
+       "os"
+       "testing"
+       "time"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/config"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+       gate "github.com/apache/dubbo-go-samples/game/go-server-gate/cmd"
+       "github.com/apache/dubbo-go-samples/game/pkg/pojo"
+)
+
+var gateProvider = gate.BasketballService{}
+
+func TestMain(m *testing.M) {
+       config.SetConsumerService(gateProvider)
+
+       hessian.RegisterPOJO(&pojo.Result{})
+       config.Load()
+       time.Sleep(3 * time.Second)
+
+       os.Exit(m.Run())
+}
diff --git 
a/integrate_test/game/go-server-gate/tests/integration/provider_test.go 
b/integrate_test/game/go-server-gate/tests/integration/provider_test.go
new file mode 100644
index 0000000..66c0f61
--- /dev/null
+++ b/integrate_test/game/go-server-gate/tests/integration/provider_test.go
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package integration
+
+import (
+       "context"
+       "testing"
+)
+
+import (
+       "github.com/stretchr/testify/assert"
+)
+
+func TestSend(t *testing.T) {
+       res, err := gateProvider.Send(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"])
+}
diff --git a/start_integrate_test.sh b/start_integrate_test.sh
index 12e29ee..11c2094 100755
--- a/start_integrate_test.sh
+++ b/start_integrate_test.sh
@@ -14,6 +14,10 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
+# game
+array+=("game/go-server-game")
+array+=("game/go-server-gate")
+
 # helloworld
 array=("helloworld")
 

Reply via email to