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")