{"id":22061510,"url":"https://github.com/raojinlin/mutagen-server","last_synced_at":"2026-05-02T14:45:13.066Z","repository":{"id":64887735,"uuid":"578220135","full_name":"raojinlin/mutagen-server","owner":"raojinlin","description":"为Mutagen提供WebSocket接口的服务器软件，旨在为Mutagen做一个Web端扩展，允许用户通过GUI创建和监控同步任务。","archived":false,"fork":false,"pushed_at":"2023-03-24T14:55:11.000Z","size":29,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-28T23:26:40.516Z","etag":null,"topics":["go","mutagen","websocket"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raojinlin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-14T14:38:44.000Z","updated_at":"2023-03-24T14:47:22.000Z","dependencies_parsed_at":"2024-06-20T06:58:56.016Z","dependency_job_id":"09feee07-4710-44c8-a180-413aa16a82ef","html_url":"https://github.com/raojinlin/mutagen-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raojinlin%2Fmutagen-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raojinlin%2Fmutagen-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raojinlin%2Fmutagen-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raojinlin%2Fmutagen-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raojinlin","download_url":"https://codeload.github.com/raojinlin/mutagen-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245138969,"owners_count":20567072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","mutagen","websocket"],"created_at":"2024-11-30T18:12:43.539Z","updated_at":"2026-05-02T14:45:13.035Z","avatar_url":"https://github.com/raojinlin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mutagen Server\n\n该项目是一个为Mutagen提供WebSocket接口的服务器软件。目前，该项目只支持文件同步接口，并支持SSH密码输入。该项目旨在为Mutagen做一个Web端扩展，允许用户通过GUI创建和监控同步任务。\n\n## 安装\n使用以下命令进行安装：\n\n```bash\n$ go get -u github.com/raojinlin/mutagen-server\n```\n\n## 使用示例\n\n命令参数\n```bash\n$ mutagen-server --help\nUsage of mutagen-server\n  -listen string\n        specify listen address (default \"127.0.0.1:8081\")\n  -sock string\n        specify daemon sock path (default \"unix:/Users/raojinlin/.mutagen/daemon/daemon.sock\")\n\n```\n\n启动服务器\n```bash\n$ mutagen-server -listen 127.0.0.1:8081 -sock ~/.mutagen/daemon//daemon.sock\n```\n你可以使用curl命令测试是否启动成功。\n```bash\n$ curl 127.0.0.1:8081\n```\n\n## 支持的接口\n* 文件同步\n  * 查询同步会话\n  * 创建同步任务\n  * 暂停同步任务\n  * 恢复同步任务\n  * 重置同步任务\n  * 终止同步任务\n\n### 查询同步会话\n```http request\nGET /api/synchronization/sessions?id=SESSION_ID\u0026label=LABEL_SELECTOR\u0026name=NAME\n```\n\n#### 参数\n* SESSION_ID: 会话ID\n* LABEL_SELECTOR: 标签选择器，```LABEL=VALUE```，与```SESSION_ID```和```NAME```参数互斥，优先取```SESSION_ID```和```NAME```\n\n#### 会话列表响应\n```json\n{\n    \"message\": \"\",\n    \"action\": \"list\",\n    \"data\": {\n        \"stateIndex\": 427168,\n        \"sessionStates\": [\n            {\n                \"session\": {\n                    \"identifier\": \"sync_cTNbmVcnIfQ5jrSfXLCZdW0UDIu7zWOfhH9Pu6Bzs1H\",\n                    \"version\": 1,\n                    \"creationTime\": {\n                        \"seconds\": 1670856053,\n                        \"nanos\": 168591000\n                    },\n                    \"creatingVersionMinor\": 15,\n                    \"creatingVersionPatch\": 2,\n                    \"alpha\": {\n                        \"path\": \"/tmp/mugaten-test1\"\n                    },\n                    \"beta\": {\n                        \"protocol\": \"ssh\",\n                        \"user\": \"raojinlin\",\n                        \"host\": \"172.31.2.19\",\n                        \"path\": \"/tmp/mutagen-sync\"\n                    },\n                    \"configuration\": {},\n                    \"configurationAlpha\": {},\n                    \"configurationBeta\": {},\n                    \"name\": \"test\",\n                    \"labels\": {\n                        \"env\": \"test\",\n                        \"for\": \"ui\",\n                        \"name\": \"test\"\n                    }\n                },\n                \"status\": \"connecting-beta\",\n                \"lastError\": \"beta scan error: unable to receive scan response: unable to read message length: unexpected EOF\",\n                \"alphaState\": {\n                    \"connected\": true\n                },\n                \"betaState\": {}\n            }\n        ]\n    },\n    \"code\": 0,\n    \"id\": 0\n}\n```\n\n### Websocket接口\n\n下面是文件同步接口配置，websocket接口请求与响应数据格式如下。\n\n请求\n```go\ntype Request struct {\n\t// 接口名称\n\tAction  string      `json:\"action\"`\n\t// 接口数据\n\tData    interface{} `json:\"data\"`\n\t// 请求ID\n\tId      int         `json:\"id\"`\n}\n```\n响应\n```go\ntype Response struct {\n\t// 接口名称\n\tAction  string      `json:\"action\"`\n\t// 如果错误码大于0则表示有错误发生，这是错误信息\t\n\tMessage string      `json:\"message\"`\n\t// 正常情况下会接口的返回值，当有错误发生时为null   \n\tData    interface{} `json:\"data\"`\n\t// 错误码，0表示正常，没有错误\n\tCode    int         `json:\"code\"`\n\t// 请求ID，用来标识请求响应ID与请求ID一致\n\tId      int         `json:\"id\"`\n}\n```\n\n\n#### 接口概览表\n\n| Action    | 描述          |\n|-----------|-------------|\n| creation  | 创建同步        |\n| list      | 查询已经创建的同步会话 |\n| pause     | 暂停会话        |\n| reset     | 重置会话        |\n| resume    | 恢复暂停的会话     |\n| terminate | 终止会话        |\n\n\n#### 创建同步\n\n请求\n```json\n{\n  \"action\": \"creation\",\n  \"id\": 1,\n  \"data\": {}\n}\n```\n\n响应\n创建参数，参考[synchronization.pb.go:27](https://github.com/mutagen-io/mutagen/tree/master/pkg/service/synchronization/synchronization.pb.go#L27)\n```json\n{\n  \"action\": \"creation\",\n  \"id\": 1,\n  \"data\": {\n    \"name\": \"\",\n    \"labels\": [],\n    \"paused\": false,\n    \"alpha\": {\n      \"kind\": 0,\n      \"protocol\": 0,\n      \"user\": \"\",\n      \"port\": 0,\n      \"environment\": {},\n      \"parameters\": {},\n      \"path\": \"\"\n    },\n    \"beta\": {\n      \"kind\": 0,\n      \"protocol\": 0,\n      \"user\": \"\",\n      \"port\": 0,\n      \"environment\": {},\n      \"parameters\": {},\n      \"path\": \"\"\n    },\n    \"configuration\": {\n      \"synchronizationMode\":    0,\n      \"maximumEntryCount\":      0,\n      \"maximumStagingFileSize\": 0,\n      \"probeMode\":              0,\n      \"scanMode\":               0,\n      \"stageMode\":              0,\n      \"symbolicLinkMode\":       0,\n      \"watchMode\":              0,\n      \"watchPollingInterval\":   0,\n      \"defaultIgnores\":         [],\n      \"ignores\":                [],\n      \"ignoreVCSMode\":          false,\n      \"permissionsMode\":        0,\n      \"defaultFileMode\":        0,\n      \"defaultDirectoryMode\":   0,\n      \"defaultOwner\":           \"\",\n      \"defaultGroup\":           \"\"\n    },\n    \"alphaConfiguration\": {\n      \"synchronizationMode\":    0,\n      \"maximumEntryCount\":      0,\n      \"maximumStagingFileSize\": 0,\n      \"probeMode\":              0,\n      \"scanMode\":               0,\n      \"stageMode\":              0,\n      \"symbolicLinkMode\":       0,\n      \"watchMode\":              0,\n      \"watchPollingInterval\":   0,\n      \"defaultIgnores\":         [],\n      \"ignores\":                [],\n      \"ignoreVCSMode\":          false,\n      \"permissionsMode\":        0,\n      \"defaultFileMode\":        0,\n      \"defaultDirectoryMode\":   0,\n      \"defaultOwner\":           \"\",\n      \"defaultGroup\":           \"\"\n    },\n    \"betaConfiguration\": {\n      \"synchronizationMode\":    0,\n      \"maximumEntryCount\":      0,\n      \"maximumStagingFileSize\": 0,\n      \"probeMode\":              0,\n      \"scanMode\":               0,\n      \"stageMode\":              0,\n      \"symbolicLinkMode\":       0,\n      \"watchMode\":              0,\n      \"watchPollingInterval\":   0,\n      \"defaultIgnores\":         [],\n      \"ignores\":                [],\n      \"ignoreVCSMode\":          0,\n      \"permissionsMode\":        0,\n      \"defaultFileMode\":        0,\n      \"defaultDirectoryMode\":   0,\n      \"defaultOwner\":           \"\",\n      \"defaultGroup\":           \"\"\n    }\n  },\n  \"error\": 0,\n  \"message\": \"\"\n}\n```\n\n#### 查询\n```json\n{\n  \"action\": \"list\",\n  \"data\": {\n    \"name\": \"test\",\n    \"id\": \"xxx\",\n    \"label\": \"x=1\"\n  }\n}\n```\n\n#### 暂停\n```json\n{\n  \"action\": \"pause\",\n  \"data\": {\n    \"name\": \"test\",\n    \"id\": \"xxx\",\n    \"label\": \"x=1\"\n  }\n}\n```\n\n#### 停止\n```json\n{\n  \"action\": \"terminate\",\n  \"data\": {\n    \"name\": \"test\",\n    \"id\": \"xxx\",\n    \"label\": \"x=1\"\n  }\n}\n```\n\n\n#### 恢复\n```json\n{\n  \"action\": \"resume\",\n  \"data\": {\n    \"name\": \"test\",\n    \"id\": \"xxx\",\n    \"label\": \"x=1\"\n  }\n}\n```\n\n\n#### 重置\n```json\n{\n  \"action\": \"reset\",\n  \"data\": {\n    \"name\": \"test\",\n    \"id\": \"xxx\",\n    \"label\": \"x=1\"\n  }\n}\n```\n\n### 客户端示例\n\n```javascript\nclass Client {\n    constructor(url=\"ws://127.0.0.1:8081/synchronization\") {\n        const websocket = new WebSocket(url)\n        websocket.onopen = function () {\n            console.log(url, \"connected\");\n        };\n\n        websocket.onmessage = (event)  =\u003e {\n            let { data } = event;\n            data = JSON.parse(data)\n            if (data.action === \"prompt\") {\n                console.log(data.message);\n                this.sendMessage(\"answer\", prompt(data.message))\n            } else if (data.action === \"message\") {\n                console.log(data.message);\n            } else if (data.action === \"error\") {\n                console.error(data.message)\n            } else {\n                console.log(data)\n            }\n        }\n        websocket.onclose = function () {\n            console.log(\"CLOSED\")\n        }\n        this.websocket = websocket\n        this.id = 1\n    }\n\n    sendMessage(action, data) {\n        const id = this.id++;\n        this.websocket.send(JSON.stringify({\n            action,\n            id,\n            data\n        }))\n    }\n\n    create(creation) {\n        this.sendMessage('creation', creation)\n    }\n\n    pause(selections) {\n        this.sendMessage('pause', selections)\n    }\n\n    reset(selections) {\n        this.sendMessage('reset', selections)\n    }\n    \n    flush(selections) {\n        this.sendMessage(\"flush\", selections)\n    }\n    \n    terminate(selections) {\n        this.sendMessage(\"terminate\", selections)\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraojinlin%2Fmutagen-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraojinlin%2Fmutagen-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraojinlin%2Fmutagen-server/lists"}