From 93b9303ee1e7541e987837ad69d33f30cf872e59 Mon Sep 17 00:00:00 2001 From: eson Date: Wed, 18 Nov 2020 19:49:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BA=A4=E6=B5=81.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- myblock/background/task.js | 5 -- myblock/background/worker.js | 56 +++++++++++---- myblock/base.js | 5 +- myblock/content/inject.js | 122 ++++++++++++-------------------- proxyserver/.gitignore | 1 + proxyserver/go.mod | 3 + proxyserver/go.sum | 8 +++ proxyserver/main_test.go | 13 ++++ proxyserver/oplog.go | 38 ++++++++++ proxyserver/queue.go | 55 +++++++++++++++ proxyserver/router.go | 130 +++++++++++++++++++++++++++++++++++ proxyserver/struct.go | 46 +++++++++++++ proxyserver/uidcompare.go | 40 +++++++++++ 14 files changed, 425 insertions(+), 99 deletions(-) delete mode 100644 myblock/background/task.js create mode 100644 proxyserver/.gitignore create mode 100644 proxyserver/main_test.go create mode 100644 proxyserver/oplog.go create mode 100644 proxyserver/queue.go create mode 100644 proxyserver/router.go create mode 100644 proxyserver/struct.go create mode 100644 proxyserver/uidcompare.go diff --git a/.gitignore b/.gitignore index 5540266..e26f460 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ *.crx -proxyserver +*.log diff --git a/myblock/background/task.js b/myblock/background/task.js deleted file mode 100644 index b421e57..0000000 --- a/myblock/background/task.js +++ /dev/null @@ -1,5 +0,0 @@ - -function ExecuteTask(response) { - window.location.href = response.url; -} -ExecuteTask() diff --git a/myblock/background/worker.js b/myblock/background/worker.js index a0ce0ac..174bd3b 100644 --- a/myblock/background/worker.js +++ b/myblock/background/worker.js @@ -2,34 +2,64 @@ var task_manager = { } -function GetTask(sender) { + +function GetRemoteTask(sender) { fetch(TaskUrl).then(function (response) { - task_manager[sender.tab.id] = response; - chrome.tabs.executeScript(sender.tab.id, { "runAt": "document_end", file: "background/task.js" }, function (results) { - }) + if (response.ok) { + response.json().then(function (value) { + // console.log(value); + if(value.code == 200) { + task_manager[sender.tab.id] ; + chrome.tabs.executeScript(sender.tab.id, {runAt: "document_end", code: `window.location.href = "${value.data.url}"` }, function (results) { + }) + Tell(sender, InjectMsgType.FETCH); + } else { + Tell(sender, InjectMsgType.NOTASK); + } + }) + } else { + console.log("error response:",response.text()) + } }).catch(function (reason) { console.log(reason); }) } chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { + // console.log(request); + sendResponse({}); + console.log(request, sender); // 利用sender tab id 返回正确的任务id switch (request.type) { case BackgroundMsgType.CONTENT: - console.log(request, task_manager, sender); // 利用sender tab id 返回正确的任务id + // TODO: 按照task id返回 拿到的内容 + // 重新获取任务 + GetRemoteTask(sender); + break; case BackgroundMsgType.ERROR: - console.log(request, task_manager, sender); // 利用sender tab id 返回正确的任务id + // TODO: 按照task id返回 错误 + // 重新获取任务 + GetRemoteTask(sender); + break; case BackgroundMsgType.GETTASK: - console.log(request, task_manager, sender); // 利用sender tab id 返回正确的任务id + GetRemoteTask(sender); + break; + case BackgroundMsgType.NOTWANT: + Tell(sender,InjectMsgType.WAIT); + break; + default: + break; } // sendResponse({type: MsgType.NEWURL, url: "https://playerduo.com/api/playerDuo-service-v2/rip113?lang=en&deviceType=browser"}); - GetTask(sender); - sendResponse(); + // GetRemoteTask(sender); }); - - - - +function Tell(sender, jnjectType) { + try { + chrome.tabs.sendMessage(sender.tab.id , {type: jnjectType}) + } catch (error) { + console.log(error); + } +} diff --git a/myblock/base.js b/myblock/base.js index d6a1ad6..127110c 100644 --- a/myblock/base.js +++ b/myblock/base.js @@ -3,15 +3,18 @@ var TaskUrl = "http://localhost:7123/task/get"; const TaskIDKey = "chrome_proxy_tid_key" const BackgroundMsgType = { - + NOTWANT: 'notwant', CONTENT: 'content', GETTASK: 'gettask', TIMEOUT: 'timeout', ERROR: 'error', + OK: 'ok', } const InjectMsgType = { FETCH: 'fetch', WAIT: 'wait', ERROR: 'error', + NOTASK: 'notask', + OK: 'ok', } diff --git a/myblock/content/inject.js b/myblock/content/inject.js index ceadccf..97540e3 100644 --- a/myblock/content/inject.js +++ b/myblock/content/inject.js @@ -1,94 +1,58 @@ -var href = window.location.href; -var content = document.documentElement.innerHTML; -if (href.startsWith("https://playerduo.com") && content.startsWith('
')) {
-  SendContent();
+ 
+chrome.runtime.onMessage.addListener(function (request) {
+  switch(request.type) {
+    case InjectMsgType.WAIT:
+      setTimeout(function(){
+        GetTask();
+      }, 6000);
+      break;
+    case InjectMsgType.NOTASK:
+      setTimeout(function(){
+        GetTask();
+      }, 4000);
+      break;
+    case InjectMsgType.FETCH:
+      setTimeout(function(){
+        GetTask();
+      }, 6000)
+      break;
+    default:
+      break;
+  }
+  // chrome.runtime.onMessage.removeListener(assignTextToTextareas);  //optional
+});
+
+if(typeof chrome.app.isInstalled != undefined){
+  var href = window.location.href;
+  var content = document.documentElement.innerHTML;
+  
+  if (href.startsWith("https://playerduo.com") && content.startsWith('
')) {
+    // SendContent();
+    Tell(BackgroundMsgType.CONTENT, content);
+  } else {
+    // NotWant()
+    Tell(BackgroundMsgType.NOTWANT, content)
+  }
 } else {
-  GetTask()
+  console.log(chrome.app);
 }
 
-
-function SendContent() {
-  chrome.runtime.sendMessage({ type: BackgroundMsgType.CONTENT, content: content },
-    function (response) {
-      console.log(response);
-      GetTask();
-    })
+function Tell(backgroundType, content) {
+  if(content == undefined) {
+    chrome.runtime.sendMessage({type: backgroundType});
+  } else {
+    chrome.runtime.sendMessage({type: backgroundType, content: content});
+  }
 }
 
 function GetTask() {
-  chrome.runtime.sendMessage({ type: BackgroundMsgType.GETTASK }, function (response) {
-    switch(response.type) {
-      case InjectMsgType.WAIT:
-        setTimeout(function(){
-          GetTask();
-        }, 1000);
-      default:
-        setTimeout(function(){
-          GetTask();
-        }, 6000)
-    }
-  })
+  Tell(BackgroundMsgType.GETTASK);
 }
 
 
 
 
-// var reset = {
-//   timeout: setTimeout(function () {
-//     chrome.runtime.sendMessage({ type: BackgroundMsgType.TIMEOUT }, function (response) { 
-//       console.log(response);
-//     })
-//     GetTask(1000);
-//   }, 7000),
-//   isCancel: false,
-// }
 
 
 
-// function GetTask(timeout) {
-//   chrome.runtime.sendMessage({ type: BackgroundMsgType.GETTASK }, function (response) {
-//     console.log("GetTask:", response.type, response);
-//     switch (response.type) {
-//       case InjectMsgType.WAIT:
-//         if (!reset.isCancel) {
-//           clearTimeout(reset.timeout);
-//           reset.isCancel = true;
-//         }
-//         setTimeout(function () {
-//           GetTask()
-//         }, timeout) // 递归获取请求
-//       case InjectMsgType.FETCH:
-//     }
-//   })
-// }
-
-// var href = window.location.href;
-// if (href.startsWith("https://playerduo.com")) {
-//   var content = document.documentElement.innerHTML;
-//   if (content.startsWith('
')) {
-//     chrome.runtime.sendMessage({ type: BackgroundMsgType.CONTENT, content: content },
-//       function (response) {
-//         console.log(response.type, response);
-//         if (response.type === BackgroundMsgType.GETTASK) {
-//           GetTask(1000); // 立即获取任务. 如果没有就等待
-//         };
-//       })
-//   }
-// }
-
-
-
-
-
-
-
-// chrome.runtime.onMessage.addListener(function (request) {
-//   if (request.type === BackgroundMsgType.CONTENT) {
-
-//   }
-
-//   // chrome.runtime.onMessage.removeListener(assignTextToTextareas);  //optional
-// });
-
-
diff --git a/proxyserver/.gitignore b/proxyserver/.gitignore
new file mode 100644
index 0000000..d0683af
--- /dev/null
+++ b/proxyserver/.gitignore
@@ -0,0 +1 @@
+proxyserver
diff --git a/proxyserver/go.mod b/proxyserver/go.mod
index 5f260a6..d5adde1 100644
--- a/proxyserver/go.mod
+++ b/proxyserver/go.mod
@@ -3,9 +3,12 @@ module git.nonolive.co/eson.hsm/proxyserver
 go 1.15
 
 require (
+	github.com/474420502/focus v0.12.0
+	github.com/bwmarrin/snowflake v0.3.0
 	github.com/gin-gonic/gin v1.6.3
 	github.com/go-playground/validator/v10 v10.4.1 // indirect
 	github.com/golang/protobuf v1.4.3 // indirect
+	github.com/google/uuid v1.1.2
 	github.com/json-iterator/go v1.1.10 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.1 // indirect
diff --git a/proxyserver/go.sum b/proxyserver/go.sum
index 339e55f..c6f4101 100644
--- a/proxyserver/go.sum
+++ b/proxyserver/go.sum
@@ -1,8 +1,14 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/474420502/focus v0.12.0 h1:+icbmj7IEOefvTegHt5EpcHt6WFbe2miIrceUJx2Evo=
+github.com/474420502/focus v0.12.0/go.mod h1:d0PMjtMxFz1a9HIhwyFPkWa+JF+0LgOrEUfd8iZka6s=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Pallinder/go-randomdata v1.1.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y=
+github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
+github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
@@ -39,6 +45,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
 github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
diff --git a/proxyserver/main_test.go b/proxyserver/main_test.go
new file mode 100644
index 0000000..fd25020
--- /dev/null
+++ b/proxyserver/main_test.go
@@ -0,0 +1,13 @@
+package main
+
+import (
+	"testing"
+)
+
+func TestMain(t *testing.T) {
+	main()
+}
+
+func TestTask(t *testing.T) {
+
+}
diff --git a/proxyserver/oplog.go b/proxyserver/oplog.go
new file mode 100644
index 0000000..9a756db
--- /dev/null
+++ b/proxyserver/oplog.go
@@ -0,0 +1,38 @@
+package main
+
+import (
+	"encoding/json"
+	"log"
+	"os"
+)
+
+var oplog *Oplog
+
+// Oplog 操作日志类
+type Oplog struct {
+	oplog *log.Logger
+}
+
+func initOplog() {
+	if oplog == nil {
+		oplog = &Oplog{}
+		f, err := os.OpenFile("./op.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
+		if err != nil {
+			panic(err)
+		}
+		oplog.oplog = log.New(f, "", log.Lmsgprefix)
+	}
+}
+
+// Write 操作日志写入
+func (op *Oplog) Write(data interface{}) {
+	if d, ok := data.(*Task); ok {
+		data, err := json.Marshal(d)
+		if err != nil {
+			log.Println(err)
+		}
+		op.oplog.Println(string(data))
+		return
+	}
+	log.Println("data must gin.H: ", data)
+}
diff --git a/proxyserver/queue.go b/proxyserver/queue.go
new file mode 100644
index 0000000..2621f9d
--- /dev/null
+++ b/proxyserver/queue.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+	"sync"
+
+	pqueuekey "github.com/474420502/focus/priority_queuekey"
+)
+
+// Queue 存储队列
+type Queue struct {
+	queue *pqueuekey.PriorityQueue
+	lock  sync.Mutex
+}
+
+// NewQueue 创建队列
+func NewQueue() *Queue {
+	q := &Queue{}
+	q.queue = pqueuekey.New(CompareTaskID)
+	return q
+}
+
+// Get 获取该值是否存在
+func (q *Queue) Get(key interface{}) (result interface{}, ok bool) {
+	q.lock.Lock()
+	defer q.lock.Unlock()
+	return q.queue.Get(key)
+}
+
+// Push 入队
+func (q *Queue) Push(key interface{}, value interface{}) {
+	q.lock.Lock()
+	defer q.lock.Unlock()
+	q.queue.Push(key, value)
+}
+
+// Pop 出队
+func (q *Queue) Pop() (result interface{}, ok bool) {
+	q.lock.Lock()
+	defer q.lock.Unlock()
+	return q.queue.Pop()
+}
+
+// Remove 删除指定key
+func (q *Queue) Remove(key interface{}) (result interface{}, ok bool) {
+	q.lock.Lock()
+	defer q.lock.Unlock()
+	return q.queue.Remove(key)
+}
+
+// Top 队头
+func (q *Queue) Top() (result interface{}, ok bool) {
+	q.lock.Lock()
+	defer q.lock.Unlock()
+	return q.queue.Top()
+}
diff --git a/proxyserver/router.go b/proxyserver/router.go
new file mode 100644
index 0000000..93a3f76
--- /dev/null
+++ b/proxyserver/router.go
@@ -0,0 +1,130 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/http"
+	"time"
+
+	"github.com/bwmarrin/snowflake"
+
+	"github.com/gin-gonic/gin"
+)
+
+var taskQueue = NewQueue()
+var waitQueue = NewQueue()
+var readyQueue = NewQueue()
+
+var snowNode *snowflake.Node
+
+func init() {
+	log.SetFlags(log.Llongfile | log.LstdFlags)
+	initOplog()
+	// Create a new Node with a Node number of 1
+	node, err := snowflake.NewNode(1)
+	if err != nil {
+		panic(err)
+	}
+	snowNode = node
+
+	engine.GET("/", func(c *gin.Context) {
+		c.JSON(200, Response{Code: 200, Message: "", Data: nil})
+	})
+
+	task := engine.Group("/task")
+	task.GET("/get", GetTask)
+	task.POST("/put", PutTask)
+
+	task.POST("/content", ContentTask)
+	task.GET("/ready", ReadyTask)
+}
+
+// GetTask 获取当前一条任务列表
+func GetTask(c *gin.Context) {
+	if result, ok := taskQueue.Pop(); ok {
+		c.JSON(http.StatusOK, Response{Code: 200, Message: "", Data: result})
+		return
+	}
+	c.JSON(http.StatusOK, Response{Code: 204, Message: "No Task"})
+}
+
+// PutTask 把一条任务放入队列
+func PutTask(c *gin.Context) {
+
+	u := c.PostForm("url")
+	if u != "" {
+		data := NewTask()
+
+		now := time.Now()
+		tid := snowNode.Generate().Base64()
+		data.Store("taskid", tid)
+		data.Store("url", u)
+		data.Store("ts", now.UnixNano())
+		taskQueue.Push(tid, data)
+		oplog.Write(data)
+		c.JSON(http.StatusOK, Response{Code: 200, Message: "ok", Data: data})
+		return
+	}
+
+	c.JSON(http.StatusOK, Response{Code: 400, Message: "url 不错在"})
+	return
+}
+
+// ContentTask 把一条任务放入队列
+func ContentTask(c *gin.Context) {
+	r := c.PostForm("response")
+	response := &Response{}
+	json.Unmarshal([]byte(r), response)
+	if response.Code == 200 {
+		data := response.Data.(gin.H)
+		tid := data["taskid"]
+		if iv, ok := waitQueue.Remove(tid); ok {
+			task := iv.(*Task)
+			task.Store("content", data["content"])
+			task.Store("is_read", "false")
+			task.Store("status", "ready")
+			readyQueue.Push(tid, task) // 进入回调发送队列.TODO: 内容持久化
+		}
+	}
+}
+
+// AckTask 确认整个任务流程完成.
+func AckTask(c *gin.Context) {
+	tid := c.Query("taskid")
+	if tid != "" {
+		if itask, ok := readyQueue.Get(tid); ok {
+			task := itask.(*Task)
+			if status, ok := task.Load("status"); ok {
+				if status.(string) == "readying" {
+					task.Store("status", "readied")
+					c.JSON(http.StatusOK, Response{Code: 200, Message: fmt.Sprintf("task %s readied", tid)})
+					return
+				}
+				c.JSON(http.StatusOK, Response{Code: 200, Message: fmt.Sprintf("task %s is not readying", tid)})
+				return
+			}
+		}
+	} else {
+		c.JSON(http.StatusOK, Response{Code: 404, Message: fmt.Sprintf("query taskid params must exist")})
+		return
+	}
+	c.JSON(http.StatusOK, Response{Code: 404, Message: fmt.Sprintf("taskid: %s is not found", tid)})
+}
+
+// ReadyTask 把一条任务放入队列
+func ReadyTask(c *gin.Context) {
+	tid := c.Query("taskid")
+	if tid != "" {
+		if itask, ok := readyQueue.Get(tid); ok {
+			task := itask.(*Task)
+			task.Store("status", "readying")
+			c.JSON(http.StatusOK, Response{Code: 200, Data: task})
+			return
+		}
+	} else {
+		c.JSON(http.StatusOK, Response{Code: 404, Message: fmt.Sprintf("query taskid params must exist")})
+		return
+	}
+	c.JSON(http.StatusOK, Response{Code: 404, Message: fmt.Sprintf("taskid: %s is not found", tid)})
+}
diff --git a/proxyserver/struct.go b/proxyserver/struct.go
new file mode 100644
index 0000000..8969143
--- /dev/null
+++ b/proxyserver/struct.go
@@ -0,0 +1,46 @@
+package main
+
+import (
+	"encoding/json"
+	"sync"
+
+	"github.com/gin-gonic/gin"
+)
+
+// Response 统一的返回格式
+type Response struct {
+	Code    int         `json:"code"`
+	Message string      `json:"msg"`
+	Data    interface{} `json:"data"`
+}
+
+// Task 任务
+type Task struct {
+	data gin.H
+	lock sync.Mutex
+}
+
+func NewTask() *Task {
+	return &Task{data: gin.H{}}
+}
+
+// Store 存储一个字段
+func (t *Task) Store(key string, value interface{}) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+	t.data[key] = value
+}
+
+// Load 取一个字段
+func (t *Task) Load(key string) (value interface{}, ok bool) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+	value, ok = t.data[key]
+	return
+}
+
+func (t *Task) MarshalJSON() ([]byte, error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+	return json.Marshal(t.data)
+}
diff --git a/proxyserver/uidcompare.go b/proxyserver/uidcompare.go
new file mode 100644
index 0000000..b03d323
--- /dev/null
+++ b/proxyserver/uidcompare.go
@@ -0,0 +1,40 @@
+package main
+
+// CompareTaskID 任务id比较
+func CompareTaskID(k1, k2 interface{}) int {
+	s1 := k2.(string)
+	s2 := k1.(string)
+
+	switch {
+	case len(s1) > len(s2):
+		for i := 0; i < len(s2); i++ {
+			if s1[i] != s2[i] {
+				if s1[i] > s2[i] {
+					return 1
+				}
+				return -1
+			}
+		}
+		return 1
+	case len(s1) < len(s2):
+		for i := 0; i < len(s1); i++ {
+			if s1[i] != s2[i] {
+				if s1[i] > s2[i] {
+					return 1
+				}
+				return -1
+			}
+		}
+		return -1
+	default:
+		for i := 0; i < len(s1); i++ {
+			if s1[i] != s2[i] {
+				if s1[i] > s2[i] {
+					return 1
+				}
+				return -1
+			}
+		}
+		return 0
+	}
+}