From 7b06ef8deaa14c624eb03e63e0bb71b936a024c6 Mon Sep 17 00:00:00 2001 From: mattuy Date: Sat, 15 Dec 2018 00:34:15 +0800 Subject: [PATCH] initial commit --- .gitignore | 2 +- design/stormchat.mdj | 9551 +++++++++++++++++ stormchat-client/res/conctrl_x64.dll | Bin 0 -> 32256 bytes stormchat-client/res/icon.ico | Bin 0 -> 9662 bytes stormchat-client/src/control.go | 60 + stormchat-client/src/main.go | 256 + stormchat-client/src/session.go | 324 + stormchat-client/src/stormchat-client.syso | Bin 0 -> 9954 bytes stormchat-client/src/user.go | 9 + stormchat-client/src/win-console.go | 158 + stormchat-server/res/stormchat.sql | 28 + stormchat-server/src/stormchat/control.go | 72 + stormchat-server/src/stormchat/err.go | 19 + stormchat-server/src/stormchat/main.go | 46 + stormchat-server/src/stormchat/message.go | 90 + stormchat-server/src/stormchat/session.go | 451 + .../src/stormchat/storm-server.go | 59 + stormchat-server/src/stormchat/user.go | 133 + 18 files changed, 11257 insertions(+), 1 deletion(-) create mode 100644 design/stormchat.mdj create mode 100644 stormchat-client/res/conctrl_x64.dll create mode 100644 stormchat-client/res/icon.ico create mode 100644 stormchat-client/src/control.go create mode 100644 stormchat-client/src/main.go create mode 100644 stormchat-client/src/session.go create mode 100644 stormchat-client/src/stormchat-client.syso create mode 100644 stormchat-client/src/user.go create mode 100644 stormchat-client/src/win-console.go create mode 100644 stormchat-server/res/stormchat.sql create mode 100644 stormchat-server/src/stormchat/control.go create mode 100644 stormchat-server/src/stormchat/err.go create mode 100644 stormchat-server/src/stormchat/main.go create mode 100644 stormchat-server/src/stormchat/message.go create mode 100644 stormchat-server/src/stormchat/session.go create mode 100644 stormchat-server/src/stormchat/storm-server.go create mode 100644 stormchat-server/src/stormchat/user.go diff --git a/.gitignore b/.gitignore index 75419e8..f475183 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ # Binaries for programs and plugins *.exe *.exe~ -*.dll +#*.dll *.so *.dylib diff --git a/design/stormchat.mdj b/design/stormchat.mdj new file mode 100644 index 0000000..d5c5be5 --- /dev/null +++ b/design/stormchat.mdj @@ -0,0 +1,9551 @@ +{ + "_type": "Project", + "_id": "AAAAAAFF+h6SjaM2Hec=", + "name": "stormchat", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFF+qBWK6M3Z8Y=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "server", + "ownedElements": [ + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFm+G3MId0ghoE=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "storm-server", + "ownedViews": [ + { + "_type": "UMLClassView", + "_id": "AAAAAAFm+LRASuNkAdE=", + "_parent": { + "$ref": "AAAAAAFm+G3MId0ghoE=" + }, + "model": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFm+LRASuNlAdM=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNkAdE=" + }, + "model": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFm+LRASuNmzYA=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNlAdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFm+LRASuNnrf0=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNlAdM=" + }, + "font": "Arial;13;1", + "left": 301, + "top": 151, + "width": 390, + "height": 13, + "text": "stormServer" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFm+LRASuNo+YA=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNlAdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -48, + "width": 74.38818359375, + "height": 13, + "text": "(from server)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFm+LRASuNpL9Q=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNlAdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 296, + "top": 144, + "width": 400, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFm+LRASuNmzYA=" + }, + "nameLabel": { + "$ref": "AAAAAAFm+LRASuNnrf0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFm+LRASuNo+YA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFm+LRASuNpL9Q=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFm+LRAS+NqEJk=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNkAdE=" + }, + "model": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFm+LoO8+ORHu4=", + "_parent": { + "$ref": "AAAAAAFm+LRAS+NqEJk=" + }, + "model": { + "$ref": "AAAAAAFm+LoOseOOhqY=" + }, + "font": "Arial;13;0", + "left": 301, + "top": 174, + "width": 390, + "height": 13, + "text": "+ChatMap[]: StormChat", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 296, + "top": 169, + "width": 400, + "height": 23 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFm+LRAS+NrDlI=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNkAdE=" + }, + "model": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAFm+LojluOXF1w=", + "_parent": { + "$ref": "AAAAAAFm+LRAS+NrDlI=" + }, + "model": { + "$ref": "AAAAAAFm+LojWOOU4vE=" + }, + "font": "Arial;13;0", + "left": 301, + "top": 197, + "width": 390, + "height": 13, + "text": "+Destroy()", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 296, + "top": 192, + "width": 400, + "height": 23 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFm+LRAS+NsLsE=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNkAdE=" + }, + "model": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFm+LRAS+Ntj4E=", + "_parent": { + "$ref": "AAAAAAFm+LRASuNkAdE=" + }, + "model": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": -24, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 296, + "top": 144, + "width": 400, + "height": 248, + "nameCompartment": { + "$ref": "AAAAAAFm+LRASuNlAdM=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFm+LRAS+NqEJk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFm+LRAS+NrDlI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFm+LRAS+NsLsE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFm+LRAS+Ntj4E=" + } + } + ] + }, + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFm+G804d1aFHo=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "storm-chat", + "ownedViews": [ + { + "_type": "UMLClassView", + "_id": "AAAAAAFnEWVvaYWDNMI=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "model": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnEWVvaYWEvNM=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWDNMI=" + }, + "model": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnEWVvaYWFQ48=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWEvNM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnEWVvaYWGa8U=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWEvNM=" + }, + "font": "Arial;13;1", + "left": 245, + "top": 127, + "width": 391, + "height": 13, + "text": "StormChat" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnEWVvaYWH67o=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWEvNM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "width": 74.38818359375, + "height": 13, + "text": "(from server)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnEWVvaoWIAy0=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWEvNM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 240, + "top": 120, + "width": 401, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnEWVvaYWFQ48=" + }, + "nameLabel": { + "$ref": "AAAAAAFnEWVvaYWGa8U=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnEWVvaYWH67o=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnEWVvaoWIAy0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnEWVvaoWJSV8=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWDNMI=" + }, + "model": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnEWnZuIWu4k8=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "model": { + "$ref": "AAAAAAFnEWnZiIWryTE=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 150, + "width": 391, + "height": 13, + "text": "+Sender: UserInfo", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnEWyr3YYLWDo=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "model": { + "$ref": "AAAAAAFnEWyrloYIf2g=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 165, + "width": 391, + "height": 13, + "text": "+Receiver: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnEWznUIYSe8c=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "model": { + "$ref": "AAAAAAFnEWznDoYPN0I=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 180, + "width": 391, + "height": 13, + "text": "+Addr: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnEWz5VoYZQ9o=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "model": { + "$ref": "AAAAAAFnEWz5PYYWY/c=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 195, + "width": 391, + "height": 13, + "text": "+Conn: net.TCPConn", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnEW141YYh7Jo=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "model": { + "$ref": "AAAAAAFnEW14k4Ye2rE=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 210, + "width": 391, + "height": 13, + "text": "+Status", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnSakoDABAPV4=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "model": { + "$ref": "AAAAAAFnSaknzQA9h10=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 225, + "width": 391, + "height": 13, + "text": "+WriteChan", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnSaeIlPzlSEA=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "model": { + "$ref": "AAAAAAFnSaeIUPziNPs=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 240, + "width": 391, + "height": 13, + "text": "+StopChan", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 240, + "top": 145, + "width": 401, + "height": 113 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnEWVvaoWKnDU=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWDNMI=" + }, + "model": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXFVPIdhRko=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXFU9odeVIE=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 263, + "width": 391, + "height": 13, + "text": "+ReceiveLoop()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXF4xoeG8/s=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXF4d4eDYps=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 278, + "width": 391, + "height": 13, + "text": "+SendLoop()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXJj+YgFy2A=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXJjtIgC21E=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 293, + "width": 391, + "height": 13, + "text": "+PingHandler()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXKIWogqe3s=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXKIBognOsg=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 308, + "width": 391, + "height": 13, + "text": "+LoginHandler(headInfo: HeadInfo)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXKo6ohGQYg=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXKo04hDb4A=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 323, + "width": 391, + "height": 13, + "text": "+LogoutHandler(HeadInfo)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXLkG4hi+ac=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXLkBIhfO7A=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 338, + "width": 391, + "height": 13, + "text": "+MessageHandler(HeadInfo)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnNJrkCs+fRlk=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnNJrjwc+cZXA=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 353, + "width": 391, + "height": 13, + "text": "+GetUserListHandler()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnNJx3l9BwN+Q=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnNJx3VtBtnX4=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 368, + "width": 391, + "height": 13, + "text": "+GetUserPhotoHandler()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnNEUs4sNNKas=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnNEUsocNKo78=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 383, + "width": 391, + "height": 13, + "text": "+UpdateUserInfoHandler(head, data)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXaxnIpTtYI=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXaxZopQL7c=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 398, + "width": 391, + "height": 13, + "text": "+TransMessage(msg: Message)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnHQDeUcF39L8=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnHOHLVLx/3c8=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 413, + "width": 391, + "height": 13, + "text": "+TransUnreadedMessages(user: UserInfo)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXYsYYogyBw=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXYsG4odrxk=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 428, + "width": 391, + "height": 13, + "text": "+Offline(oldChat: StormChat)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXWjvYnNnY8=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXWjeInK3VY=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 443, + "width": 391, + "height": 13, + "text": "+SendData(HeadInfo, data []byte)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXSNEomVoYs=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXSMy4mSlKM=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 458, + "width": 391, + "height": 13, + "text": "+SendPanic(curOperation: string, err: string)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXPIjokF61M=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXPIW4kCkf0=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 473, + "width": 391, + "height": 13, + "text": "-send([]byte, []byte)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXGVXIeiwzs=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXGVR4efI0Q=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 488, + "width": 391, + "height": 13, + "text": "-waitData()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnEXOCAojXmGU=", + "_parent": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "model": { + "$ref": "AAAAAAFnEXOBu4jUIMs=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 503, + "width": 391, + "height": 13, + "text": "-readDataWithLength(maxLength: int16)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 240, + "top": 258, + "width": 401, + "height": 263 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnEWVvaoWLRA0=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWDNMI=" + }, + "model": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnEWVvaoWMG6E=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWDNMI=" + }, + "model": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 240, + "top": 120, + "width": 401, + "height": 681, + "nameCompartment": { + "$ref": "AAAAAAFnEWVvaYWEvNM=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnEWVvaoWJSV8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnEWVvaoWKnDU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnEWVvaoWLRA0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnEWVvaoWMG6E=" + } + }, + { + "_type": "UMLEnumerationView", + "_id": "AAAAAAFnEW3HG4Yn2uw=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "model": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnEW3HG4YowBo=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4Yn2uw=" + }, + "model": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnEW3HG4YpU54=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4YowBo=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 125, + "width": 151, + "height": 13, + "text": "«enumeration»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnEW3HG4YqruA=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4YowBo=" + }, + "font": "Arial;13;1", + "left": 21, + "top": 140, + "width": 151, + "height": 13, + "text": "ChatStatus" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnEW3HG4YrANU=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4YowBo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "width": 74.38818359375, + "height": 13, + "text": "(from server)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnEW3HG4YsudY=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4YowBo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 16, + "top": 120, + "width": 161, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFnEW3HG4YpU54=" + }, + "nameLabel": { + "$ref": "AAAAAAFnEW3HG4YqruA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnEW3HG4YrANU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnEW3HG4YsudY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnEW3HG4Yt1ZQ=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4Yn2uw=" + }, + "model": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnEW3HG4YuReM=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4Yn2uw=" + }, + "model": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnEW3HG4YvUCk=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4Yn2uw=" + }, + "model": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnEW3HG4YwyUg=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4Yn2uw=" + }, + "model": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "width": 10, + "height": 10 + }, + { + "_type": "UMLEnumerationLiteralCompartmentView", + "_id": "AAAAAAFnEW3HHIYx9Bc=", + "_parent": { + "$ref": "AAAAAAFnEW3HG4Yn2uw=" + }, + "model": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "subViews": [ + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnEW53C4ZdZic=", + "_parent": { + "$ref": "AAAAAAFnEW3HHIYx9Bc=" + }, + "model": { + "$ref": "AAAAAAFnEW52y4Zawso=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 163, + "width": 151, + "height": 13, + "text": "Created", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnEW6k5IZkTT8=", + "_parent": { + "$ref": "AAAAAAFnEW3HHIYx9Bc=" + }, + "model": { + "$ref": "AAAAAAFnEW6ksIZhQUw=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 178, + "width": 151, + "height": 13, + "text": "Running", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnEW62zYZra8g=", + "_parent": { + "$ref": "AAAAAAFnEW3HHIYx9Bc=" + }, + "model": { + "$ref": "AAAAAAFnEW62tYZoR1g=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 193, + "width": 151, + "height": 13, + "text": "Stopped", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnEW8SL4Zy0wI=", + "_parent": { + "$ref": "AAAAAAFnEW3HHIYx9Bc=" + }, + "model": { + "$ref": "AAAAAAFnEW8R8oZvC94=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 208, + "width": 151, + "height": 13, + "text": "RecvClosed", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnEW/+Z4Z7+tI=", + "_parent": { + "$ref": "AAAAAAFnEW3HHIYx9Bc=" + }, + "model": { + "$ref": "AAAAAAFnEW/+IoZ4QEo=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 223, + "width": 151, + "height": 13, + "text": "Destroyed", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 16, + "top": 158, + "width": 161, + "height": 83 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 16, + "top": 120, + "width": 161, + "height": 153, + "nameCompartment": { + "$ref": "AAAAAAFnEW3HG4YowBo=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFnEW3HG4Yt1ZQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnEW3HG4YuReM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnEW3HG4YvUCk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnEW3HG4YwyUg=" + }, + "enumerationLiteralCompartment": { + "$ref": "AAAAAAFnEW3HHIYx9Bc=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF5+zJ/7OaVE=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 120, + "width": 333.751953125, + "height": 25, + "text": "StormChat,一个session,处理一个客户的事务" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6ENK//d+34=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 168, + "width": 333.751953125, + "height": 25, + "text": "Sender,消息发送者(客户身份)" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6Hr2AAf67s=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 192, + "width": 333.751953125, + "height": 25, + "text": "Receiver,消息接收者" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6KV2ACdnAQ=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 216, + "width": 333.751953125, + "height": 25, + "text": "Addr,远程客户端地址" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6MOVAEKugk=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 240, + "width": 333.751953125, + "height": 25, + "text": "Conn,与客户的TCP连接" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6NiewE0GSE=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 264, + "width": 333.751953125, + "height": 25, + "text": "Status,当前Session状态" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6Pb7QFi4aE=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 352, + "width": 333.751953125, + "height": 25, + "text": "ReceiveLoop(),消息接收循环线程" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6RUcwGVIQQ=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 376, + "width": 333.751953125, + "height": 25, + "text": "SendLoop(),消息发送循环线程" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6TqyAHObCE=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 400, + "width": 333.751953125, + "height": 25, + "text": "PingHandler(),心跳包到达事件处理函数" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6VrhwIB0Cg=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 424, + "width": 333.751953125, + "height": 25, + "text": "LoginHandler(),登录请求处理函数" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6X5OAJEG9U=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 448, + "width": 333.751953125, + "height": 25, + "text": "LogoutHandler(),登出请求处理函数" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6ZBQAJo5+k=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 472, + "width": 333.751953125, + "height": 25, + "text": "MessageHandler(),消息到达处理函数" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF6asewKS0sI=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 568, + "width": 333.751953125, + "height": 25, + "text": "TransMessage(),转发消息到目标客户" + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAFnF6x5vANWYps=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "model": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnF6x5vANXN80=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANWYps=" + }, + "model": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnF6x5vANYfYI=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANXN80=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF6x5vANZHJk=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANXN80=" + }, + "font": "Arial;13;1", + "left": 21, + "top": 295, + "width": 151, + "height": 13, + "text": "HeadInfo" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF6x5vANae7A=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANXN80=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -48, + "width": 74.38818359375, + "height": 13, + "text": "(from server)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF6x5vANblg4=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANXN80=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 16, + "top": 288, + "width": 161, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnF6x5vANYfYI=" + }, + "nameLabel": { + "$ref": "AAAAAAFnF6x5vANZHJk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnF6x5vANae7A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnF6x5vANblg4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnF6x5vANcRXM=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANWYps=" + }, + "model": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnF64oJAWmnmw=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANcRXM=" + }, + "model": { + "$ref": "AAAAAAFnF64n4gWgwPM=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 318, + "width": 151, + "height": 13, + "text": "+map[string]string", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 16, + "top": 313, + "width": 161, + "height": 23 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnF6x5vQNdv24=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANWYps=" + }, + "model": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + }, + "font": "Arial;13;0", + "left": 16, + "top": 336, + "width": 161, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnF6x5vQNeSmU=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANWYps=" + }, + "model": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnF6x5vQNfrqg=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANWYps=" + }, + "model": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -24, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 16, + "top": 288, + "width": 161, + "height": 105, + "nameCompartment": { + "$ref": "AAAAAAFnF6x5vANXN80=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnF6x5vANcRXM=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnF6x5vQNdv24=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnF6x5vQNeSmU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnF6x5vQNfrqg=" + } + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnF6yirgOTEb0=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 16, + "top": 352, + "width": 160.9599609375, + "height": 32, + "text": "解析JSON得到的map数据" + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAFnF63FfgTH+e0=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTDJrc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTILqA=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTDJrc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 202, + "top": 387, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTJkX8=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTDJrc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 197, + "top": 401, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTKgWc=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTDJrc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 213, + "top": 358, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTLMCU=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTEm/8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 209, + "top": 389, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTMg6c=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTEm/8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 202, + "top": 401, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTNPVI=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTEm/8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 222, + "top": 364, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTOy8Y=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTFJFk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 196, + "top": 384, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTPuOs=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTFJFk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 194, + "top": 398, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnF63FfgTQfZM=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTFJFk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 201, + "top": 357, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnF63FfgTR3cE=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTEm/8=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnF63FfgTS0WM=", + "_parent": { + "$ref": "AAAAAAFnF63FfgTH+e0=" + }, + "model": { + "$ref": "AAAAAAFnF63FfQTFJFk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAFnF6x5vANWYps=" + }, + "tail": { + "$ref": "AAAAAAFnEWVvaYWDNMI=" + }, + "lineStyle": 1, + "points": "239:390;177:368", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFnF63FfgTILqA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFnF63FfgTJkX8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnF63FfgTKgWc=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAFnF63FfgTLMCU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAFnF63FfgTMg6c=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAFnF63FfgTNPVI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAFnF63FfgTOy8Y=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAFnF63FfgTPuOs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAFnF63FfgTQfZM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAFnF63FfgTR3cE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAFnF63FfgTS0WM=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF7W+vguHgVA=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 616, + "width": 333.751953125, + "height": 25, + "text": "Offline(),勒令用户下线" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF7ab/AvV55A=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 640, + "width": 333.751953125, + "height": 25, + "text": "SendData(),发送数据到客户端" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF7gWbA6pwnE=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 664, + "width": 333.751953125, + "height": 25, + "text": "SendPanic(),发送Panic消息到客户端,断开连接" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF7jcJQ9AuyM=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 720, + "width": 333.751953125, + "height": 25, + "text": "waitData(),等待客户端数据,并监控Status变化" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF7swshEZ84s=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 696, + "width": 333.751953125, + "height": 25, + "text": "send(),将要发送给客户端的数据发送到写循环线程" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF75+CBdmdQM=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 744, + "width": 333.751953125, + "height": 25, + "text": "readDataWinthLength(),从TCP连接中读出数据" + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAFnHGiwobHwLWA=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHsuQA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobHx8bY=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHsuQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 198, + "top": 287, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobHyv+o=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHsuQA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 189, + "top": 299, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobHzaZA=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHsuQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 217, + "top": 264, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobH0Pu8=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHtB+k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 209, + "top": 295, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobH1mwk=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHtB+k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 199, + "top": 305, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobH2emA=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHtB+k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 229, + "top": 276, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobH38DY=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHuup8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 188, + "top": 279, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobH47Y8=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHuup8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 182, + "top": 291, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGiwobH5v4M=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHuup8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 201, + "top": 255, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnHGiwobH6SAQ=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHtB+k=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnHGiwobH7Acc=", + "_parent": { + "$ref": "AAAAAAFnHGiwobHwLWA=" + }, + "model": { + "$ref": "AAAAAAFnHGiwoLHuup8=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAFnEW3HG4Yn2uw=" + }, + "tail": { + "$ref": "AAAAAAFnEWVvaYWDNMI=" + }, + "lineStyle": 1, + "points": "239:306;177:258", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFnHGiwobHx8bY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFnHGiwobHyv+o=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnHGiwobHzaZA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAFnHGiwobH0Pu8=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAFnHGiwobH1mwk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAFnHGiwobH2emA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAFnHGiwobH38DY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAFnHGiwobH47Y8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAFnHGiwobH5v4M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAFnHGiwobH6SAQ=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAFnHGiwobH7Acc=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHOKpEL3X7TU=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 592, + "width": 333.751953125, + "height": 25, + "text": "TransUnreadedMessages(),用户登录时转发未读消息" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNEYMi8SAYDA=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 544, + "width": 333.751953125, + "height": 25, + "text": "UpdateUserInfoHandler(),更新用户信息" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNJzn+dG8VUo=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 496, + "width": 333.751953125, + "height": 25, + "text": "GetUserListHandler(),请求好友列表处理函数" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNJz2kdHx7Fc=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 520, + "width": 333.751953125, + "height": 25, + "text": "GetUserPhotoHandler(),请求用户头像处理函数" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnSagt6f+Wz7c=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 288, + "width": 333.751953125, + "height": 25, + "text": "WriteChan,数据发送通道" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnSah+Zf/YZG8=", + "_parent": { + "$ref": "AAAAAAFm+G804d1aFHo=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 312, + "width": 333.751953125, + "height": 25, + "text": "StopChan,写消息循环终止通道,由读循环控制" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFm+LL2dOMTiuY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "stormChat", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFm+LNTkeNFZBk=", + "_parent": { + "$ref": "AAAAAAFm+LL2dOMTiuY=" + }, + "name": "receiver", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFm+LOjOeNMVDw=", + "_parent": { + "$ref": "AAAAAAFm+LL2dOMTiuY=" + }, + "name": "addr", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFm+LPSeeNUtvU=", + "_parent": { + "$ref": "AAAAAAFm+LL2dOMTiuY=" + }, + "name": "conn", + "type": "" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAFm+LQM1eNbPsE=", + "_parent": { + "$ref": "AAAAAAFm+LL2dOMTiuY=" + }, + "name": "destroy" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFm+LRASeNiRy4=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "stormServer", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFm+LoOseOOhqY=", + "_parent": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "name": "ChatMap[]", + "type": "StormChat" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAFm+LojWOOU4vE=", + "_parent": { + "$ref": "AAAAAAFm+LRASeNiRy4=" + }, + "name": "Destroy" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnEWVvaYWB2bQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "StormChat", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnEXBQR4Z/6/w=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnEXBQR4aA5pk=", + "_parent": { + "$ref": "AAAAAAFnEXBQR4Z/6/w=" + }, + "reference": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnEXBQR4aBFak=", + "_parent": { + "$ref": "AAAAAAFnEXBQR4Z/6/w=" + }, + "reference": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnF63FfQTDJrc=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnF63FfQTEm/8=", + "_parent": { + "$ref": "AAAAAAFnF63FfQTDJrc=" + }, + "reference": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnF63FfQTFJFk=", + "_parent": { + "$ref": "AAAAAAFnF63FfQTDJrc=" + }, + "reference": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnHGiwoLHsuQA=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGiwoLHtB+k=", + "_parent": { + "$ref": "AAAAAAFnHGiwoLHsuQA=" + }, + "reference": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGiwoLHuup8=", + "_parent": { + "$ref": "AAAAAAFnHGiwoLHsuQA=" + }, + "reference": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "aggregation": "composite" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWnZiIWryTE=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "Sender", + "type": { + "$ref": "AAAAAAFnEWqAz4W4XMc=" + } + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWyrloYIf2g=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "Receiver", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWznDoYPN0I=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "Addr", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWz5PYYWY/c=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "Conn", + "type": "net.TCPConn" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEW14k4Ye2rE=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "Status", + "type": "" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnSaknzQA9h10=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "WriteChan", + "type": "" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnSaeIUPziNPs=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "StopChan", + "type": "" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXFU9odeVIE=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "ReceiveLoop" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXF4d4eDYps=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "SendLoop" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXJjtIgC21E=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "PingHandler" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXKIBognOsg=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "LoginHandler", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnF6u02AMcEJA=", + "_parent": { + "$ref": "AAAAAAFnEXKIBognOsg=" + }, + "name": "headInfo", + "type": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + } + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXKo04hDb4A=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "LogoutHandler", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnF6wF9AMxgrc=", + "_parent": { + "$ref": "AAAAAAFnEXKo04hDb4A=" + }, + "name": "HeadInfo", + "type": "" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXLkBIhfO7A=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "MessageHandler", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnF65/QQYCBK4=", + "_parent": { + "$ref": "AAAAAAFnEXLkBIhfO7A=" + }, + "name": "HeadInfo", + "type": "" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnNJrjwc+cZXA=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "GetUserListHandler" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnNJx3VtBtnX4=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "GetUserPhotoHandler" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnNEUsocNKo78=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "UpdateUserInfoHandler", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnNEW7gcOBER4=", + "_parent": { + "$ref": "AAAAAAFnNEUsocNKo78=" + }, + "name": "head", + "type": "" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnNEb1DMTUXeY=", + "_parent": { + "$ref": "AAAAAAFnNEUsocNKo78=" + }, + "name": "data", + "type": "" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXaxZopQL7c=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "TransMessage", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXbd94pviZ0=", + "_parent": { + "$ref": "AAAAAAFnEXaxZopQL7c=" + }, + "name": "msg", + "type": "Message" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnHOHLVLx/3c8=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "TransUnreadedMessages", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHOI8aLy2EFo=", + "_parent": { + "$ref": "AAAAAAFnHOHLVLx/3c8=" + }, + "name": "user", + "type": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + } + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXYsG4odrxk=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "Offline", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXZ9u4o8Ohc=", + "_parent": { + "$ref": "AAAAAAFnEXYsG4odrxk=" + }, + "name": "oldChat", + "type": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + } + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXWjeInK3VY=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "SendData", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXX3eonpuE0=", + "_parent": { + "$ref": "AAAAAAFnEXWjeInK3VY=" + }, + "name": "HeadInfo", + "type": "" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXX3eonqcX0=", + "_parent": { + "$ref": "AAAAAAFnEXWjeInK3VY=" + }, + "name": "data []byte", + "type": "" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXSMy4mSlKM=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "SendPanic", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXUtBomxzxc=", + "_parent": { + "$ref": "AAAAAAFnEXSMy4mSlKM=" + }, + "name": "curOperation", + "type": "string" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXUtB4myJGA=", + "_parent": { + "$ref": "AAAAAAFnEXSMy4mSlKM=" + }, + "name": "err", + "type": "string" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXPIW4kCkf0=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "send", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXQAw4kfUOM=", + "_parent": { + "$ref": "AAAAAAFnEXPIW4kCkf0=" + }, + "name": "[]byte", + "type": "" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnEXQAxIkgaG8=", + "_parent": { + "$ref": "AAAAAAFnEXPIW4kCkf0=" + }, + "name": "[]byte", + "type": "" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXGVR4efI0Q=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "waitData", + "visibility": "private" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnEXOBu4jUIMs=", + "_parent": { + "$ref": "AAAAAAFnEWVvaYWB2bQ=" + }, + "name": "readDataWithLength", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnF79TahiTxxE=", + "_parent": { + "$ref": "AAAAAAFnEXOBu4jUIMs=" + }, + "name": "maxLength", + "type": "int16" + } + ] + } + ] + }, + { + "_type": "UMLEnumeration", + "_id": "AAAAAAFnEW3HGoYlYQQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "ChatStatus", + "literals": [ + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnEW52y4Zawso=", + "_parent": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "name": "Created" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnEW6ksIZhQUw=", + "_parent": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "name": "Running" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnEW62tYZoR1g=", + "_parent": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "name": "Stopped" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnEW8R8oZvC94=", + "_parent": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "name": "RecvClosed" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnEW/+IoZ4QEo=", + "_parent": { + "$ref": "AAAAAAFnEW3HGoYlYQQ=" + }, + "name": "Destroyed" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnF6x5vANUQRA=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "HeadInfo", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnF64n4gWgwPM=", + "_parent": { + "$ref": "AAAAAAFnF6x5vANUQRA=" + }, + "name": "map[string]string", + "type": "" + } + ] + }, + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFnF7Co3Af+aBY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "message", + "ownedViews": [ + { + "_type": "UMLClassView", + "_id": "AAAAAAFnF7DtHggQ1Is=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "model": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnF7DtHggRKdA=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggQ1Is=" + }, + "model": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnF7DtHggSnPM=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggRKdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -144, + "top": -16, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF7DtHggTdq0=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggRKdA=" + }, + "font": "Arial;13;1", + "left": 269, + "top": 79, + "width": 319, + "height": 13, + "text": "Message" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF7DtHggUd1Q=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggRKdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -144, + "top": -16, + "width": 74.38818359375, + "height": 13, + "text": "(from server)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF7DtHggVoG8=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggRKdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -144, + "top": -16, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 264, + "top": 72, + "width": 329, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnF7DtHggSnPM=" + }, + "nameLabel": { + "$ref": "AAAAAAFnF7DtHggTdq0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnF7DtHggUd1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnF7DtHggVoG8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnF7DtHggWJFs=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggQ1Is=" + }, + "model": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnF7ET+wg78tY=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggWJFs=" + }, + "model": { + "$ref": "AAAAAAFnF7ETugg4dHY=" + }, + "font": "Arial;13;0", + "left": 269, + "top": 102, + "width": 319, + "height": 13, + "text": "+When: Time", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnF7GenQhHUsk=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggWJFs=" + }, + "model": { + "$ref": "AAAAAAFnF7GeYwhE1Wo=" + }, + "font": "Arial;13;0", + "left": 269, + "top": 117, + "width": 319, + "height": 13, + "text": "+From UserInfo", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnF8T6shvg9Co=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggWJFs=" + }, + "model": { + "$ref": "AAAAAAFnF8T6gRvdDz0=" + }, + "font": "Arial;13;0", + "left": 269, + "top": 132, + "width": 319, + "height": 13, + "text": "+To: UserInfo", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnF7HqxghOHIY=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggWJFs=" + }, + "model": { + "$ref": "AAAAAAFnF7HqighLw+E=" + }, + "font": "Arial;13;0", + "left": 269, + "top": 147, + "width": 319, + "height": 13, + "text": "+Msg: byte", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 264, + "top": 97, + "width": 329, + "height": 68 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnF7DtHggXvzQ=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggQ1Is=" + }, + "model": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnF9MLJRwARgM=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggXvzQ=" + }, + "model": { + "$ref": "AAAAAAFnF9MK8Bv967Y=" + }, + "font": "Arial;13;0", + "left": 269, + "top": 170, + "width": 319, + "height": 13, + "text": "+Save()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnHQDeYsGA+2Y=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggXvzQ=" + }, + "model": { + "$ref": "AAAAAAFnHME3IbpNHo0=" + }, + "font": "Arial;13;0", + "left": 269, + "top": 185, + "width": 319, + "height": 13, + "text": "+QuerySavedMessages(user: UserInfo): Messages", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 264, + "top": 165, + "width": 329, + "height": 38 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnF7DtHggYF1Q=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggQ1Is=" + }, + "model": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -72, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnF7DtHggZjZg=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggQ1Is=" + }, + "model": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -72, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 264, + "top": 72, + "width": 329, + "height": 265, + "nameCompartment": { + "$ref": "AAAAAAFnF7DtHggRKdA=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnF7DtHggWJFs=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnF7DtHggXvzQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnF7DtHggYF1Q=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnF7DtHggZjZg=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF85QHRvogp0=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 72, + "width": 329, + "height": 25, + "text": "定义一条客户消息" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF86clhvxXrY=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 120, + "width": 329, + "height": 25, + "text": "When,服务器接收消息的时间" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF87o0xv3ZVY=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 144, + "width": 329, + "height": 25, + "text": "From,消息发送者" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF9NEixwEDYg=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 168, + "width": 329, + "height": 25, + "text": "To,消息接收者" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF9RGQRwPf98=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 192, + "width": 329, + "height": 27, + "text": "\nMsg,消息内容" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnF9S+txwY94A=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 232, + "width": 329, + "height": 27, + "text": "\nSave(),将消息存储到数据库,标准Base64编码" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHMF+ALpXrHw=", + "_parent": { + "$ref": "AAAAAAFnF7Co3Af+aBY=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 256, + "width": 355.1689453125, + "height": 27, + "text": "QuerySavedMessages(),查询用户未读消息,解码后返回" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnF7DtHggOpZA=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Message", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnF7ETugg4dHY=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "name": "When", + "type": "Time" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnF7GeYwhE1Wo=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "name": "From UserInfo", + "type": "" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnF8T6gRvdDz0=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "name": "To", + "type": { + "$ref": "AAAAAAFnEWqAz4W4XMc=" + } + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnF7HqighLw+E=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "name": "Msg", + "type": "byte" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAFnF9MK8Bv967Y=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "name": "Save" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnHME3IbpNHo0=", + "_parent": { + "$ref": "AAAAAAFnF7DtHggOpZA=" + }, + "name": "QuerySavedMessages", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHMFu0rpUNtw=", + "_parent": { + "$ref": "AAAAAAFnHME3IbpNHo0=" + }, + "type": "Messages", + "direction": "return" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHMO1lbpeGTs=", + "_parent": { + "$ref": "AAAAAAFnHME3IbpNHo0=" + }, + "name": "user", + "type": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + } + } + ] + } + ] + }, + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFnF+LbDx2rrJU=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "user", + "ownedViews": [ + { + "_type": "UMLClassView", + "_id": "AAAAAAFnF+MPOh3Ah9c=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "model": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnF+MPOh3B2qU=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3Ah9c=" + }, + "model": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnF+MPOh3C2a4=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3B2qU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": -432, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF+MPOh3D3b4=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3B2qU=" + }, + "font": "Arial;13;1", + "left": 365, + "top": 111, + "width": 279, + "height": 13, + "text": "UserInfo" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF+MPOx3ETNU=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3B2qU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": -432, + "width": 74.38818359375, + "height": 13, + "text": "(from server)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnF+MPOx3FORU=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3B2qU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": -432, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 104, + "width": 289, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnF+MPOh3C2a4=" + }, + "nameLabel": { + "$ref": "AAAAAAFnF+MPOh3D3b4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnF+MPOx3ETNU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnF+MPOx3FORU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnF+MPOx3GT1E=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3Ah9c=" + }, + "model": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnHF0praQxI8w=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3GT1E=" + }, + "model": { + "$ref": "AAAAAAFnHF0paKQue3s=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 134, + "width": 279, + "height": 13, + "text": "+User: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnHF1NBKQ400o=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3GT1E=" + }, + "model": { + "$ref": "AAAAAAFnHF1M0qQ1ZdQ=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 149, + "width": 279, + "height": 13, + "text": "+NickName: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnHF1+GqQ//bo=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3GT1E=" + }, + "model": { + "$ref": "AAAAAAFnHF196qQ8FaI=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 164, + "width": 279, + "height": 13, + "text": "+Motto: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnHF2SQaRGd3c=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3GT1E=" + }, + "model": { + "$ref": "AAAAAAFnHF2SJqRDyZg=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 179, + "width": 279, + "height": 13, + "text": "+UGroup: UserGroup", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 129, + "width": 289, + "height": 68 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnF+MPOx3Hu30=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3Ah9c=" + }, + "model": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnHGxn7rUX64A=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "model": { + "$ref": "AAAAAAFnHGxntrUUPQI=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 202, + "width": 279, + "height": 13, + "text": "+QueryUserInfo(username: string): UserInfo", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnNIovKMvDK10=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "model": { + "$ref": "AAAAAAFnNIou5svA2E0=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 217, + "width": 279, + "height": 13, + "text": "+GetUserPhoto()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnHG5RNLW9Kno=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "model": { + "$ref": "AAAAAAFnHG5RCrW6s4U=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 232, + "width": 279, + "height": 13, + "text": "+Login(user: string, pwd: string): UserInfo", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnHH+oP7efH7c=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "model": { + "$ref": "AAAAAAFnHH+oB7ec5iI=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 247, + "width": 279, + "height": 13, + "text": "+GetUserList(): UserInfos", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnNEGSN8EFdBs=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "model": { + "$ref": "AAAAAAFnNEGR78EC40I=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 262, + "width": 279, + "height": 13, + "text": "+UpdateNickName(nickname: string)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnNEIlysFIRF0=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "model": { + "$ref": "AAAAAAFnNEIllsFFV4Q=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 277, + "width": 279, + "height": 13, + "text": "+UpdatePassword(pwd: string)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnNELSRMGCeG4=", + "_parent": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "model": { + "$ref": "AAAAAAFnNELSC8F/wmA=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 292, + "width": 279, + "height": 13, + "text": "+UpdateMotto(motto: string)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 197, + "width": 289, + "height": 113 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnF+MPOx3Ir0E=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3Ah9c=" + }, + "model": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -24, + "top": -216, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnF+MPOx3Jv6A=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh3Ah9c=" + }, + "model": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -24, + "top": -216, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 360, + "top": 104, + "width": 289, + "height": 329, + "nameCompartment": { + "$ref": "AAAAAAFnF+MPOh3B2qU=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnF+MPOx3GT1E=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnF+MPOx3Hu30=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnF+MPOx3Ir0E=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnF+MPOx3Jv6A=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGDD3KZXhY4=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 104, + "width": 329, + "height": 25, + "text": "UserInfo,用户信息" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGFaC6i8nvI=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 152, + "width": 329, + "height": 25, + "text": "User,用户名" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGHrcqlz90c=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 176, + "width": 329, + "height": 25, + "text": "NickName,昵称(12字以内)" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGWkYa2qj6A=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 200, + "width": 329, + "height": 25, + "text": "Motto,签名" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGXYu63OCGk=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 224, + "width": 329, + "height": 25, + "text": "UGroup,用户组,标识用户类型" + }, + { + "_type": "UMLEnumerationView", + "_id": "AAAAAAFnHGdeda68Fuw=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "model": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnHGdeda69+eQ=", + "_parent": { + "$ref": "AAAAAAFnHGdeda68Fuw=" + }, + "model": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnHGdeda6+3AQ=", + "_parent": { + "$ref": "AAAAAAFnHGdeda69+eQ=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 485, + "width": 279, + "height": 13, + "text": "«enumeration»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnHGdeda6/zHE=", + "_parent": { + "$ref": "AAAAAAFnHGdeda69+eQ=" + }, + "font": "Arial;13;1", + "left": 365, + "top": 500, + "width": 279, + "height": 13, + "text": "UserGroup" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnHGdeda7ANxU=", + "_parent": { + "$ref": "AAAAAAFnHGdeda69+eQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1184, + "top": 165, + "width": 74.38818359375, + "height": 13, + "text": "(from server)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnHGdeda7BDws=", + "_parent": { + "$ref": "AAAAAAFnHGdeda69+eQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1184, + "top": 165, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 480, + "width": 289, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFnHGdeda6+3AQ=" + }, + "nameLabel": { + "$ref": "AAAAAAFnHGdeda6/zHE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnHGdeda7ANxU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnHGdeda7BDws=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnHGdeda7C104=", + "_parent": { + "$ref": "AAAAAAFnHGdeda68Fuw=" + }, + "model": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -384, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnHGdeda7D46s=", + "_parent": { + "$ref": "AAAAAAFnHGdeda68Fuw=" + }, + "model": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -384, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnHGdeda7E8ZA=", + "_parent": { + "$ref": "AAAAAAFnHGdeda68Fuw=" + }, + "model": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -384, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnHGdeda7F6Gw=", + "_parent": { + "$ref": "AAAAAAFnHGdeda68Fuw=" + }, + "model": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -384, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLEnumerationLiteralCompartmentView", + "_id": "AAAAAAFnHGdeda7G6+Y=", + "_parent": { + "$ref": "AAAAAAFnHGdeda68Fuw=" + }, + "model": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "subViews": [ + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnHGdeda7HkwI=", + "_parent": { + "$ref": "AAAAAAFnHGdeda7G6+Y=" + }, + "model": { + "$ref": "AAAAAAFnHF5YU6R71+g=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 523, + "width": 279, + "height": 13, + "text": "User", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnHGdeda7IVxk=", + "_parent": { + "$ref": "AAAAAAFnHGdeda7G6+Y=" + }, + "model": { + "$ref": "AAAAAAFnHF5rxaSCsIQ=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 538, + "width": 279, + "height": 13, + "text": "Vip", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnHGdeda7JbWM=", + "_parent": { + "$ref": "AAAAAAFnHGdeda7G6+Y=" + }, + "model": { + "$ref": "AAAAAAFnHF6LOaSJQiU=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 553, + "width": 279, + "height": 13, + "text": "Admin", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnHGdeda7KWwU=", + "_parent": { + "$ref": "AAAAAAFnHGdeda7G6+Y=" + }, + "model": { + "$ref": "AAAAAAFnHGZJBa4BuKs=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 568, + "width": 279, + "height": 13, + "text": "Group", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 518, + "width": 289, + "height": 68 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 360, + "top": 480, + "width": 289, + "height": 137, + "nameCompartment": { + "$ref": "AAAAAAFnHGdeda69+eQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFnHGdeda7C104=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnHGdeda7D46s=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnHGdeda7E8ZA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnHGdeda7F6Gw=" + }, + "enumerationLiteralCompartment": { + "$ref": "AAAAAAFnHGdeda7G6+Y=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAFnHGh+SbFiJxY=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFeoFk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SbFjvfk=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFeoFk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 518, + "top": 449, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SbFkqZ8=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFeoFk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 533, + "top": 449, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SbFlV7U=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFeoFk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 489, + "top": 450, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SbFmLxU=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFfN6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 519, + "top": 452, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SrFn/wE=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFfN6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 532, + "top": 455, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SrFomvc=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFfN6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 491, + "top": 448, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SrFpw9Q=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFgji0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 519, + "top": 447, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SrFq3kM=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFgji0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 532, + "top": 444, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnHGh+SrFr8No=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFgji0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 491, + "top": 451, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnHGh+SrFsUKg=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFfN6M=" + }, + "visible": false, + "font": "Arial;13;0", + "top": 32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnHGh+SrFtPHI=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFiJxY=" + }, + "model": { + "$ref": "AAAAAAFnHGh+SbFgji0=" + }, + "visible": false, + "font": "Arial;13;0", + "top": 32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAFnHGdeda68Fuw=" + }, + "tail": { + "$ref": "AAAAAAFnF+MPOh3Ah9c=" + }, + "lineStyle": 1, + "points": "504:433;504:479", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFnHGh+SbFjvfk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFnHGh+SbFkqZ8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnHGh+SbFlV7U=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAFnHGh+SbFmLxU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAFnHGh+SrFn/wE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAFnHGh+SrFomvc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAFnHGh+SrFpw9Q=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAFnHGh+SrFq3kM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAFnHGh+SrFr8No=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAFnHGh+SrFsUKg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAFnHGh+SrFtPHI=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGnbWbLtmq8=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 480, + "width": 329, + "height": 25, + "text": "UserGroup,用户组,定义用户类型" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGpPErNQ2i4=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 520, + "width": 329, + "height": 25, + "text": "User,普通用户" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGqEWbODSNc=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 544, + "width": 329, + "height": 25, + "text": "Vip,氪金用户" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGras7P82O8=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 568, + "width": 329, + "height": 25, + "text": "Admin,管理员账户" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHGsWyLQqk6Q=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 704, + "top": 591, + "width": 329, + "height": 25, + "text": "Group,群组" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHHXINLb8A6g=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 264, + "width": 329, + "height": 25, + "text": "QueryUserInfo(),查询指定用户信息" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHHaBXbdgsYw=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 312, + "width": 329, + "height": 25, + "text": "Login(),根据用户名和密码匹配用户" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHH/wxLfQ018=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 336, + "width": 329, + "height": 25, + "text": "GetUserList(),获取用户信息列表(不含头像)" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNEMmRcHOXrg=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 360, + "width": 329, + "height": 25, + "text": "UpdateNickName(),更改昵称" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNEOn2cJCCEc=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 384, + "width": 329, + "height": 25, + "text": "UpdatePassword(),更改密码" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNEP1AMKWAUo=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 408, + "width": 329, + "height": 25, + "text": "UpdateMotto(),更改签名" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNIsE08yc2Sg=", + "_parent": { + "$ref": "AAAAAAFnF+LbDx2rrJU=" + }, + "font": "Arial;13;0", + "left": 712, + "top": 288, + "width": 329, + "height": 25, + "text": "GetUserPhoto(),获取用户头像数据" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnF+MPOh2+3go=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "UserInfo", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnHGBztaUBOxE=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGBztaUC6+4=", + "_parent": { + "$ref": "AAAAAAFnHGBztaUBOxE=" + }, + "reference": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGBztaUD/Io=", + "_parent": { + "$ref": "AAAAAAFnHGBztaUBOxE=" + }, + "reference": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnHGgCGq/1DQc=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGgCGq/25C8=", + "_parent": { + "$ref": "AAAAAAFnHGgCGq/1DQc=" + }, + "reference": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGgCGq/3BGY=", + "_parent": { + "$ref": "AAAAAAFnHGgCGq/1DQc=" + }, + "reference": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnHGgnQrA+bvw=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGgnQrA/+r4=", + "_parent": { + "$ref": "AAAAAAFnHGgnQrA+bvw=" + }, + "reference": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGgnQrBAN7c=", + "_parent": { + "$ref": "AAAAAAFnHGgnQrA+bvw=" + }, + "reference": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnHGhKdbD0b70=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGhKdbD1Kts=", + "_parent": { + "$ref": "AAAAAAFnHGhKdbD0b70=" + }, + "reference": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGhKdbD2cz4=", + "_parent": { + "$ref": "AAAAAAFnHGhKdbD0b70=" + }, + "reference": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "aggregation": "shared" + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnHGh+SbFeoFk=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGh+SbFfN6M=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFeoFk=" + }, + "reference": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGh+SbFgji0=", + "_parent": { + "$ref": "AAAAAAFnHGh+SbFeoFk=" + }, + "reference": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "aggregation": "composite" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnHF0paKQue3s=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "User", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnHF1M0qQ1ZdQ=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "NickName", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnHF196qQ8FaI=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "Motto", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnHF2SJqRDyZg=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "UGroup", + "type": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + } + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAFnHGxntrUUPQI=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "QueryUserInfo", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHGyi1rUzAYA=", + "_parent": { + "$ref": "AAAAAAFnHGxntrUUPQI=" + }, + "name": "username", + "type": "string" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHG4/4rWmb6M=", + "_parent": { + "$ref": "AAAAAAFnHGxntrUUPQI=" + }, + "type": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnNIou5svA2E0=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "GetUserPhoto" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnHG5RCrW6s4U=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "Login", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHHWJYLa+/wc=", + "_parent": { + "$ref": "AAAAAAFnHG5RCrW6s4U=" + }, + "name": "user", + "type": "string" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHHWJYba/1zw=", + "_parent": { + "$ref": "AAAAAAFnHG5RCrW6s4U=" + }, + "name": "pwd", + "type": "string" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHHWlbbbYpcc=", + "_parent": { + "$ref": "AAAAAAFnHG5RCrW6s4U=" + }, + "type": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnHH+oB7ec5iI=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "GetUserList", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnHH/iw7e7VoA=", + "_parent": { + "$ref": "AAAAAAFnHH+oB7ec5iI=" + }, + "type": "UserInfos", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnNEGR78EC40I=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "UpdateNickName", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnNEH+EcEol1I=", + "_parent": { + "$ref": "AAAAAAFnNEGR78EC40I=" + }, + "name": "nickname", + "type": "string" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnNEIllsFFV4Q=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "UpdatePassword", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnNEK/7MFrhaw=", + "_parent": { + "$ref": "AAAAAAFnNEIllsFFV4Q=" + }, + "name": "pwd", + "type": "string" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnNELSC8F/wmA=", + "_parent": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + }, + "name": "UpdateMotto", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnNEMMh8Gpufg=", + "_parent": { + "$ref": "AAAAAAFnNELSC8F/wmA=" + }, + "name": "motto", + "type": "string" + } + ] + } + ] + }, + { + "_type": "UMLEnumeration", + "_id": "AAAAAAFnHF4MoqRKqMY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "UserGroup", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnHGBdzaSXm54=", + "_parent": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGBdzaSYh5Q=", + "_parent": { + "$ref": "AAAAAAFnHGBdzaSXm54=" + }, + "reference": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnHGBdzaSZ3dg=", + "_parent": { + "$ref": "AAAAAAFnHGBdzaSXm54=" + }, + "reference": { + "$ref": "AAAAAAFnF+MPOh2+3go=" + } + } + } + ], + "literals": [ + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnHF5YU6R71+g=", + "_parent": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "name": "User" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnHF5rxaSCsIQ=", + "_parent": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "name": "Vip" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnHF6LOaSJQiU=", + "_parent": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "name": "Admin" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnHGZJBa4BuKs=", + "_parent": { + "$ref": "AAAAAAFnHF4MoqRKqMY=" + }, + "name": "Group" + } + ] + } + ] + }, + { + "_type": "UMLModel", + "_id": "AAAAAAFm+GxoNtz31qw=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "common", + "ownedElements": [ + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFm+MaskuOd1fg=", + "_parent": { + "$ref": "AAAAAAFm+GxoNtz31qw=" + }, + "name": "message", + "ownedViews": [ + { + "_type": "RectangleView", + "_id": "AAAAAAFm+Mkj7uPlg1g=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 192, + "top": 96, + "width": 193, + "height": 160 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFm+MlnGuPqOjg=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 472, + "top": 96, + "width": 497, + "height": 160 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFm+MmMQePuImY=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 104, + "top": 96, + "width": 89, + "height": 160 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFm+MmpIuPyTfg=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 384, + "top": 96, + "width": 89, + "height": 160 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+MvNo+QZPxE=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 120, + "top": 144, + "width": 62, + "height": 25, + "text": "包头长度" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+M16N+Rtz70=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 112, + "top": 168, + "width": 75, + "height": 25, + "text": "大端字节序" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+M6X5eR+smY=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;18;0", + "left": 104, + "top": 56, + "width": 187.029296875, + "height": 32, + "text": "Server-Client通信规则" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+M7NY+SCBUo=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 120, + "top": 192, + "width": 60, + "height": 25, + "text": "len = 4B" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+M7/vOSHrTA=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 216, + "top": 176, + "width": 145.0908203125, + "height": 25, + "text": "包头,由Operation决定" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+M/douSPDWk=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 400, + "top": 144, + "width": 62, + "height": 25, + "text": "数据长度" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+NBTleSW4TE=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 392, + "top": 168, + "width": 75, + "height": 25, + "text": "大端字节序" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+NB4g+ScPhM=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 400, + "top": 192, + "width": 60, + "height": 25, + "text": "len = 4B" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFm+NCc4eSgILE=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 648, + "top": 152, + "width": 127, + "height": 25, + "text": "长数据,由包头决定" + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAFnB/GmZ0LPano=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnB/GmZ0LQBBs=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LPano=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnB/GmZ0LRJ6M=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LQBBs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 688, + "top": -32, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/GmZ0LSVCc=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LQBBs=" + }, + "font": "Arial;13;1", + "left": 293, + "top": 375, + "width": 303, + "height": 13, + "text": "Head" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/GmZ0LTQeA=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LQBBs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 688, + "top": -32, + "width": 88.1181640625, + "height": 13, + "text": "(from common)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/GmZ0LUJKU=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LQBBs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 688, + "top": -32, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 368, + "width": 313, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnB/GmZ0LRJ6M=" + }, + "nameLabel": { + "$ref": "AAAAAAFnB/GmZ0LSVCc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnB/GmZ0LTQeA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnB/GmZ0LUJKU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnB/GmZ0LVtTs=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LPano=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnB/JpT0MDDSE=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LVtTs=" + }, + "model": { + "$ref": "AAAAAAFnB/JpGUMAMdM=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 398, + "width": 303, + "height": 13, + "text": "+Token: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCFqg47NT+9g=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LVtTs=" + }, + "model": { + "$ref": "AAAAAAFnCFqgsLNQb/0=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 413, + "width": 303, + "height": 13, + "text": "+Operation: Operations", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 393, + "width": 313, + "height": 38 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnB/GmZ0LWxMU=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LPano=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "font": "Arial;13;0", + "left": 288, + "top": 431, + "width": 313, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnB/GmZ0LXX6I=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LPano=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 344, + "top": -16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnB/GmZ0LYnUE=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LPano=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 344, + "top": -16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 288, + "top": 368, + "width": 313, + "height": 113, + "nameCompartment": { + "$ref": "AAAAAAFnB/GmZ0LQBBs=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnB/GmZ0LVtTs=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnB/GmZ0LWxMU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnB/GmZ0LXX6I=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnB/GmZ0LYnUE=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnB/O8SUMbArk=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 368, + "width": 492.3798828125, + "height": 25, + "text": "Token,消息编号,由发送方生成,接受方处理后返回相同Token(如有返回数据)", + "wordWrap": false + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAFnB/P+CUM2h7g=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnB/P+CUM3vHo=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM2h7g=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnB/P+CUM4y5Q=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM3vHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 332, + "top": -877, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/P+CUM5z8U=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM3vHo=" + }, + "font": "Arial;13;1", + "left": 197, + "top": 103, + "width": 183, + "height": 13, + "text": "Head" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/P+CUM6qjE=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM3vHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 332, + "top": -877, + "width": 88.1181640625, + "height": 13, + "text": "(from common)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/P+CUM7jUU=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM3vHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 332, + "top": -877, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 192, + "top": 96, + "width": 193, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnB/P+CUM4y5Q=" + }, + "nameLabel": { + "$ref": "AAAAAAFnB/P+CUM5z8U=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnB/P+CUM6qjE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnB/P+CUM7jUU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnB/P+CUM8ppM=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM2h7g=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnB/P+CUM9svo=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM8ppM=" + }, + "model": { + "$ref": "AAAAAAFnB/JpGUMAMdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -47, + "top": -335, + "width": 183, + "height": 13, + "text": "+Token: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCFqg5bNWuWQ=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM8ppM=" + }, + "model": { + "$ref": "AAAAAAFnCFqgsLNQb/0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -64, + "top": 32, + "width": 135.4970703125, + "height": 13, + "text": "+Operation: Operations", + "horizontalAlignment": 0 + } + ], + "visible": false, + "font": "Arial;13;0", + "left": 192, + "top": -20, + "width": 193, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnB/P+CUM+Zno=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM2h7g=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "font": "Arial;13;0", + "left": 192, + "top": 121, + "width": 193, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnB/P+CUM/eUo=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM2h7g=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 272, + "top": -429, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnB/P+CUNAz/E=", + "_parent": { + "$ref": "AAAAAAFnB/P+CUM2h7g=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 272, + "top": -429, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 192, + "top": 96, + "width": 193, + "height": 52, + "nameCompartment": { + "$ref": "AAAAAAFnB/P+CUM3vHo=" + }, + "suppressAttributes": true, + "attributeCompartment": { + "$ref": "AAAAAAFnB/P+CUM8ppM=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnB/P+CUM+Zno=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnB/P+CUM/eUo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnB/P+CUNAz/E=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAFnB/tAVUOm4D4=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnB/tAVUOnI0Q=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOm4D4=" + }, + "model": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnB/tAVUOoWDA=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOnI0Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": 368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/tAVUOp+wk=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOnI0Q=" + }, + "font": "Arial;13;1", + "left": 293, + "top": 855, + "width": 303, + "height": 13, + "text": "SenderHead" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/tAVUOqri4=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOnI0Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": 368, + "width": 88.1181640625, + "height": 13, + "text": "(from common)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnB/tAVUOr28U=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOnI0Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": 368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 848, + "width": 313, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnB/tAVUOoWDA=" + }, + "nameLabel": { + "$ref": "AAAAAAFnB/tAVUOp+wk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnB/tAVUOqri4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnB/tAVUOr28U=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnB/tAVUOsNNw=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOm4D4=" + }, + "model": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCIXVL+CtL9A=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOsNNw=" + }, + "model": { + "$ref": "AAAAAAFnCIXU/uCqkk0=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 878, + "width": 303, + "height": 13, + "text": "+Params", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 873, + "width": 313, + "height": 23 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnB/tAVUOtW20=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOm4D4=" + }, + "model": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "font": "Arial;13;0", + "left": 288, + "top": 896, + "width": 313, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnB/tAVUOuwQk=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOm4D4=" + }, + "model": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnB/tAVUOv+r8=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOm4D4=" + }, + "model": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 288, + "top": 848, + "width": 313, + "height": 89, + "nameCompartment": { + "$ref": "AAAAAAFnB/tAVUOnI0Q=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnB/tAVUOsNNw=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnB/tAVUOtW20=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnB/tAVUOuwQk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnB/tAVUOv+r8=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnB/0/FUeAUnk=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 1024, + "width": 376, + "height": 25, + "text": "Results,参数,由Operation决定,详见operation说明图" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCFwRObRss6c=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 392, + "width": 377, + "height": 25, + "text": "Operation,执行的操作名称" + }, + { + "_type": "UMLEnumerationView", + "_id": "AAAAAAFnCGJSWraVVWw=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnCGJSWraWeX0=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraVVWw=" + }, + "model": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnCGJSWraX+5U=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraWeX0=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 541, + "width": 303, + "height": 13, + "text": "«enumeration»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCGJSWraYxS0=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraWeX0=" + }, + "font": "Arial;13;1", + "left": 293, + "top": 556, + "width": 303, + "height": 13, + "text": "Operations" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCGJSWraZCrA=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraWeX0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 592, + "top": 320, + "width": 88.1181640625, + "height": 13, + "text": "(from common)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCGJSWraatYo=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraWeX0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 592, + "top": 320, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 536, + "width": 313, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFnCGJSWraX+5U=" + }, + "nameLabel": { + "$ref": "AAAAAAFnCGJSWraYxS0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnCGJSWraZCrA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnCGJSWraatYo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnCGJSWrab6Y0=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraVVWw=" + }, + "model": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnCGJSWracy6Q=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraVVWw=" + }, + "model": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnCGJSWradov4=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraVVWw=" + }, + "model": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnCGJSWraeG3M=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraVVWw=" + }, + "model": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLEnumerationLiteralCompartmentView", + "_id": "AAAAAAFnCGJSWraf2OI=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraVVWw=" + }, + "model": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "subViews": [ + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnCPW051mphr4=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnCPW0mFmm2/k=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 579, + "width": 303, + "height": 13, + "text": "Panic", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnCGRXaLy+43g=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnCGRXMLy4Bb0=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 594, + "width": 303, + "height": 13, + "text": "TransMessage", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnCL6ID+w8dgI=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnCL6HzOw5F3o=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 609, + "width": 303, + "height": 13, + "text": "SendMessage", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnDNSmwM7I+lg=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnDNSmdc7FPgA=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 624, + "width": 303, + "height": 13, + "text": "Ping", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnCGSpwr0xHDQ=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnCGSpgr0r+FQ=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 639, + "width": 303, + "height": 13, + "text": "Login", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnDdBFkNOsZjY=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnDdBFTdOpQvw=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 654, + "width": 303, + "height": 13, + "text": "Logout", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnD9vlwak+Cbg=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnD9vlbKk7PfU=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 669, + "width": 303, + "height": 13, + "text": "Offline", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnCGlEQMcS6QI=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnCGlD8scMQVU=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 684, + "width": 303, + "height": 13, + "text": "GetUserList", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnHQCFLsBXRWg=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnHPTor7+hW/0=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 699, + "width": 303, + "height": 13, + "text": "UpdateUserInfo", + "horizontalAlignment": 0 + }, + { + "_type": "UMLEnumerationLiteralView", + "_id": "AAAAAAFnNIEKLslPDyE=", + "_parent": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + }, + "model": { + "$ref": "AAAAAAFnNGffsskwM3o=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 714, + "width": 303, + "height": 13, + "text": "Literal1", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 574, + "width": 313, + "height": 158 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 288, + "top": 536, + "width": 313, + "height": 273, + "nameCompartment": { + "$ref": "AAAAAAFnCGJSWraWeX0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFnCGJSWrab6Y0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnCGJSWracy6Q=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnCGJSWradov4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnCGJSWraeG3M=" + }, + "enumerationLiteralCompartment": { + "$ref": "AAAAAAFnCGJSWraf2OI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAFnCGPW5bvAfB4=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu8hGY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvBz4Y=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu8hGY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 458, + "top": 501, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvCF+E=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu8hGY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 473, + "top": 501, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvDfyg=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu8hGY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 429, + "top": 502, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvEnkk=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu9YGY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 459, + "top": 500, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvFnag=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu9YGY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 472, + "top": 503, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvGn/A=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu9YGY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 431, + "top": 496, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvHNo8=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu+SVM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 459, + "top": 503, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvIh9I=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu+SVM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 472, + "top": 500, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCGPW5bvJvew=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu+SVM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 431, + "top": 507, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnCGPW5bvKA6U=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu9YGY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAFnCGPW5bvLgIM=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bvAfB4=" + }, + "model": { + "$ref": "AAAAAAFnCGPW5bu+SVM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -24, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAFnCGJSWraVVWw=" + }, + "tail": { + "$ref": "AAAAAAFnB/GmZ0LPano=" + }, + "lineStyle": 1, + "points": "444:481;444:535", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFnCGPW5bvBz4Y=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFnCGPW5bvCF+E=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnCGPW5bvDfyg=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAFnCGPW5bvEnkk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAFnCGPW5bvFnag=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAFnCGPW5bvGn/A=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAFnCGPW5bvHNo8=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAFnCGPW5bvIh9I=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAFnCGPW5bvJvew=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAFnCGPW5bvKA6U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAFnCGPW5bvLgIM=" + } + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCGvzbctSDBs=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 184, + "top": 368, + "width": 101, + "height": 25, + "text": "消息头基本信息" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCGx4ZMws6lo=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 224, + "top": 536, + "width": 62, + "height": 25, + "text": "执行操作" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCGzWJcxlsI4=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 616, + "width": 377, + "height": 25, + "text": "TransMessage,服务器转发消息" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCG7yz81miW0=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 688, + "width": 377, + "height": 25, + "text": "Login,客户端登陆操作" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCG9uVs2olKQ=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 760, + "width": 377, + "height": 25, + "text": "GetUserList,客户端获取好友列表" + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAFnCHRdb9B4LG8=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnCHRdb9B5wws=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B4LG8=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnCHRdb9B6ngw=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B5wws=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -248, + "top": -39, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHRdb9B77AQ=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B5wws=" + }, + "font": "Arial;13;1", + "left": 29, + "top": 855, + "width": 183, + "height": 13, + "text": "Head" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHRdb9B8w74=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B5wws=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -248, + "top": -39, + "width": 88.1181640625, + "height": 13, + "text": "(from common)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHRdb9B9Jmc=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B5wws=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -248, + "top": -39, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 24, + "top": 848, + "width": 193, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnCHRdb9B6ngw=" + }, + "nameLabel": { + "$ref": "AAAAAAFnCHRdb9B77AQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnCHRdb9B8w74=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnCHRdb9B9Jmc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnCHRdb9B+MO0=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B4LG8=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCHRdb9B/e9M=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B+MO0=" + }, + "model": { + "$ref": "AAAAAAFnB/JpGUMAMdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -627, + "top": 503, + "width": 183, + "height": 13, + "text": "+Token: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCHRdb9CAowY=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B+MO0=" + }, + "model": { + "$ref": "AAAAAAFnCFqgsLNQb/0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -644, + "top": 870, + "width": 135.4970703125, + "height": 13, + "text": "+Operation: Operations", + "horizontalAlignment": 0 + } + ], + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 732, + "width": 193, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnCHRdb9CBdQg=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B4LG8=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 873, + "width": 193, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnCHRdb9CC8ww=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B4LG8=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 323, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnCHRdb9CDibY=", + "_parent": { + "$ref": "AAAAAAFnCHRdb9B4LG8=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 323, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 848, + "width": 193, + "height": 73, + "nameCompartment": { + "$ref": "AAAAAAFnCHRdb9B5wws=" + }, + "suppressAttributes": true, + "attributeCompartment": { + "$ref": "AAAAAAFnCHRdb9B+MO0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnCHRdb9CBdQg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnCHRdb9CC8ww=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnCHRdb9CDibY=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFnCHSVXtFJVnQ=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnCHSVXtFHBsE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCHSVXtFKsUc=", + "_parent": { + "$ref": "AAAAAAFnCHSVXtFJVnQ=" + }, + "model": { + "$ref": "AAAAAAFnCHSVXtFHBsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 251, + "top": 895, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnCHSVXtFJVnQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCHSVXtFLCpg=", + "_parent": { + "$ref": "AAAAAAFnCHSVXtFJVnQ=" + }, + "model": { + "$ref": "AAAAAAFnCHSVXtFHBsE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 251, + "top": 910, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnCHSVXtFJVnQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCHSVXtFMXC8=", + "_parent": { + "$ref": "AAAAAAFnCHSVXtFJVnQ=" + }, + "model": { + "$ref": "AAAAAAFnCHSVXtFHBsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 252, + "top": 866, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnCHSVXtFJVnQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAFnCHRdb9B4LG8=" + }, + "tail": { + "$ref": "AAAAAAFnB/tAVUOm4D4=" + }, + "lineStyle": 1, + "points": "287:888;217:886", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFnCHSVXtFKsUc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFnCHSVXtFLCpg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnCHSVXtFMXC8=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAFnCHpyXtg9Qx4=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnCHpyXtg+Spc=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg9Qx4=" + }, + "model": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnCHpyXtg/PF4=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg+Spc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -64, + "top": 192, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHpyXthAkss=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg+Spc=" + }, + "font": "Arial;13;1", + "left": 293, + "top": 1031, + "width": 303, + "height": 13, + "text": "ResponseHead" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHpyXthB47s=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg+Spc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -64, + "top": 192, + "width": 88.1181640625, + "height": 13, + "text": "(from common)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHpyXthCc6A=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg+Spc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -64, + "top": 192, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 1024, + "width": 313, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnCHpyXtg/PF4=" + }, + "nameLabel": { + "$ref": "AAAAAAFnCHpyXthAkss=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnCHpyXthB47s=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnCHpyXthCc6A=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnCHpyXthDhbA=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg9Qx4=" + }, + "model": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCIVMS99wDZg=", + "_parent": { + "$ref": "AAAAAAFnCHpyXthDhbA=" + }, + "model": { + "$ref": "AAAAAAFnCIVMEt9qVYo=" + }, + "font": "Arial;13;0", + "left": 293, + "top": 1054, + "width": 303, + "height": 13, + "text": "+Results", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 288, + "top": 1049, + "width": 313, + "height": 23 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnCHpyXthE9Nk=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg9Qx4=" + }, + "model": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "font": "Arial;13;0", + "left": 288, + "top": 1072, + "width": 313, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnCHpyXthFg68=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg9Qx4=" + }, + "model": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnCHpyX9hGqpQ=", + "_parent": { + "$ref": "AAAAAAFnCHpyXtg9Qx4=" + }, + "model": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 96, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 288, + "top": 1024, + "width": 313, + "height": 97, + "nameCompartment": { + "$ref": "AAAAAAFnCHpyXtg+Spc=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnCHpyXthDhbA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnCHpyXthE9Nk=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnCHpyXthFg68=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnCHpyX9hGqpQ=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAFnCHtq1Nmoepc=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnCHtq1NmpLYE=", + "_parent": { + "$ref": "AAAAAAFnCHtq1Nmoepc=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnCHtq1NmqtFk=", + "_parent": { + "$ref": "AAAAAAFnCHtq1NmpLYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -644, + "top": 238, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHtq1NmrAp0=", + "_parent": { + "$ref": "AAAAAAFnCHtq1NmpLYE=" + }, + "font": "Arial;13;1", + "left": 29, + "top": 1031, + "width": 183, + "height": 13, + "text": "Head" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHtq1Nms9gE=", + "_parent": { + "$ref": "AAAAAAFnCHtq1NmpLYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -644, + "top": 238, + "width": 88.1181640625, + "height": 13, + "text": "(from common)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnCHtq1NmtYQg=", + "_parent": { + "$ref": "AAAAAAFnCHtq1NmpLYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -644, + "top": 238, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 24, + "top": 1024, + "width": 193, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnCHtq1NmqtFk=" + }, + "nameLabel": { + "$ref": "AAAAAAFnCHtq1NmrAp0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnCHtq1Nms9gE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnCHtq1NmtYQg=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnCHtq1NmuIhc=", + "_parent": { + "$ref": "AAAAAAFnCHtq1Nmoepc=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCHtq1NmvWeU=", + "_parent": { + "$ref": "AAAAAAFnCHtq1NmuIhc=" + }, + "model": { + "$ref": "AAAAAAFnB/JpGUMAMdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1023, + "top": 780, + "width": 183, + "height": 13, + "text": "+Token: string", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFnCHtq1Nmw/Iw=", + "_parent": { + "$ref": "AAAAAAFnCHtq1NmuIhc=" + }, + "model": { + "$ref": "AAAAAAFnCFqgsLNQb/0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1040, + "top": 1147, + "width": 135.4970703125, + "height": 13, + "text": "+Operation: Operations", + "horizontalAlignment": 0 + } + ], + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 908, + "width": 193, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnCHtq1NmxuiI=", + "_parent": { + "$ref": "AAAAAAFnCHtq1Nmoepc=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 1049, + "width": 193, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnCHtq1NmywIQ=", + "_parent": { + "$ref": "AAAAAAFnCHtq1Nmoepc=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 499, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnCHtq1Nmzeqc=", + "_parent": { + "$ref": "AAAAAAFnCHtq1Nmoepc=" + }, + "model": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 499, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 1024, + "width": 193, + "height": 73, + "nameCompartment": { + "$ref": "AAAAAAFnCHtq1NmpLYE=" + }, + "suppressAttributes": true, + "attributeCompartment": { + "$ref": "AAAAAAFnCHtq1NmuIhc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnCHtq1NmxuiI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnCHtq1NmywIQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnCHtq1Nmzeqc=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFnCHu3ltoLyoU=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "model": { + "$ref": "AAAAAAFnCHu3ltoJx+Q=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCHu3ltoMpaY=", + "_parent": { + "$ref": "AAAAAAFnCHu3ltoLyoU=" + }, + "model": { + "$ref": "AAAAAAFnCHu3ltoJx+Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 251, + "top": 1073, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnCHu3ltoLyoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCHu3ltoNEFE=", + "_parent": { + "$ref": "AAAAAAFnCHu3ltoLyoU=" + }, + "model": { + "$ref": "AAAAAAFnCHu3ltoJx+Q=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 251, + "top": 1088, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFnCHu3ltoLyoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFnCHu3ltoODbY=", + "_parent": { + "$ref": "AAAAAAFnCHu3ltoLyoU=" + }, + "model": { + "$ref": "AAAAAAFnCHu3ltoJx+Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 252, + "top": 1044, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFnCHu3ltoLyoU=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAFnCHtq1Nmoepc=" + }, + "tail": { + "$ref": "AAAAAAFnCHpyXtg9Qx4=" + }, + "lineStyle": 1, + "points": "287:1066;217:1064", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFnCHu3ltoMpaY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFnCHu3ltoNEFE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnCHu3ltoODbY=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCIYd1+DZTto=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 848, + "width": 377, + "height": 25, + "text": "Params,参数,由Operation决定,详见operation说明图" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCL7PSOyLyF0=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 640, + "width": 377, + "height": 25, + "text": "SendMessage,客户端发送消息" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCPX1bFozJBo=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 592, + "width": 377, + "height": 25, + "text": "Panic,数据异常,服务器断开连接" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnDNTq8M8Ih7M=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 664, + "width": 377, + "height": 25, + "text": "Ping,客户端发送心跳包" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnDdBv+NPfi2w=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 712, + "width": 377, + "height": 25, + "text": "Logout,用户登出" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnD9xsB6sDcxo=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 736, + "width": 377, + "height": 25, + "text": "Offline,服务器勒令下线(账号被另一客户登录)" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnF7K3iAicAxA=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 200, + "width": 96.6708984375, + "height": 25, + "text": "JSON序列化" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHPbAnr/QD2g=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 784, + "width": 377, + "height": 25, + "text": "UpdateUserInfo,客户端请求更改昵称、密码、签名或头像" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnbjBn64PCDXo=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 192, + "top": 224, + "width": 192.78076171875, + "height": 25, + "text": "至少包含Operation和Token字段" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnbjOHRYdgvm0=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 632, + "top": 536, + "width": 377, + "height": 33, + "text": "Operation决定包头需要携带的信息,详细定义见operation图" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnrTfiTu07lXc=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 120, + "top": 120, + "width": 62, + "height": 25, + "text": "【必须】" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnrTjqte4Jxjk=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 400, + "top": 120, + "width": 62, + "height": 25, + "text": "【必须】" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnrTkHfe5HC1g=", + "_parent": { + "$ref": "AAAAAAFm+MaskuOd1fg=" + }, + "font": "Arial;13;0", + "left": 256, + "top": 152, + "width": 62, + "height": 25, + "text": "【必须】" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnB/GmZ0LNVTQ=", + "_parent": { + "$ref": "AAAAAAFm+GxoNtz31qw=" + }, + "name": "Head", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnCGN4oro+bt4=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGN4oro/ibw=", + "_parent": { + "$ref": "AAAAAAFnCGN4oro+bt4=" + }, + "reference": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGN4orpAZYU=", + "_parent": { + "$ref": "AAAAAAFnCGN4oro+bt4=" + }, + "reference": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnCGPW5bu8hGY=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGPW5bu9YGY=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bu8hGY=" + }, + "reference": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGPW5bu+SVM=", + "_parent": { + "$ref": "AAAAAAFnCGPW5bu8hGY=" + }, + "reference": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + } + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnB/JpGUMAMdM=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "name": "Token", + "type": "string" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnCFqgsLNQb/0=", + "_parent": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + }, + "name": "Operation", + "type": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + } + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnB/tAVUOkVvY=", + "_parent": { + "$ref": "AAAAAAFm+GxoNtz31qw=" + }, + "name": "SenderHead", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnB/vJKEPQqWY=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnB/vJKEPRo7U=", + "_parent": { + "$ref": "AAAAAAFnB/vJKEPQqWY=" + }, + "reference": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnB/vJKEPSV0g=", + "_parent": { + "$ref": "AAAAAAFnB/vJKEPQqWY=" + }, + "reference": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + } + } + }, + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFnCHSVXtFHBsE=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "source": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "target": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnCIXU/uCqkk0=", + "_parent": { + "$ref": "AAAAAAFnB/tAVUOkVvY=" + }, + "name": "Params", + "type": "" + } + ] + }, + { + "_type": "UMLEnumeration", + "_id": "AAAAAAFnCGJSWbaTRcY=", + "_parent": { + "$ref": "AAAAAAFm+GxoNtz31qw=" + }, + "name": "Operations", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnCGLvQ7e8Mpo=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGLvQ7e9Hdc=", + "_parent": { + "$ref": "AAAAAAFnCGLvQ7e8Mpo=" + }, + "reference": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGLvQ7e+EGs=", + "_parent": { + "$ref": "AAAAAAFnCGLvQ7e8Mpo=" + }, + "reference": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnCGMW/rhNFjE=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGMW/rhOFig=", + "_parent": { + "$ref": "AAAAAAFnCGMW/rhNFjE=" + }, + "reference": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGMW/rhPte8=", + "_parent": { + "$ref": "AAAAAAFnCGMW/rhNFjE=" + }, + "reference": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAFnCGNg27mt690=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGNg27mu7bQ=", + "_parent": { + "$ref": "AAAAAAFnCGNg27mt690=" + }, + "reference": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAFnCGNg27mvtaU=", + "_parent": { + "$ref": "AAAAAAFnCGNg27mt690=" + }, + "reference": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + } + } + } + ], + "literals": [ + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnCPW0mFmm2/k=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "Panic" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnCGRXMLy4Bb0=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "TransMessage" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnCL6HzOw5F3o=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "SendMessage" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnDNSmdc7FPgA=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "Ping" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnCGSpgr0r+FQ=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "Login" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnDdBFTdOpQvw=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "Logout" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnD9vlbKk7PfU=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "Offline" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnCGlD8scMQVU=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "GetUserList" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnHPTor7+hW/0=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "UpdateUserInfo" + }, + { + "_type": "UMLEnumerationLiteral", + "_id": "AAAAAAFnNGffsskwM3o=", + "_parent": { + "$ref": "AAAAAAFnCGJSWbaTRcY=" + }, + "name": "Literal1" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnCHpyXdg7Uic=", + "_parent": { + "$ref": "AAAAAAFm+GxoNtz31qw=" + }, + "name": "ResponseHead", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFnCHu3ltoJx+Q=", + "_parent": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "source": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "target": { + "$ref": "AAAAAAFnB/GmZ0LNVTQ=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnCIVMEt9qVYo=", + "_parent": { + "$ref": "AAAAAAFnCHpyXdg7Uic=" + }, + "name": "Results", + "type": "" + } + ] + }, + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFnCJD5xebaqTo=", + "_parent": { + "$ref": "AAAAAAFm+GxoNtz31qw=" + }, + "name": "operation", + "ownedViews": [ + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCJGmiedYJb0=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;18;0", + "left": 24, + "top": 48, + "width": 125.048828125, + "height": 30, + "text": "Operation说明" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCJIDWedeuHw=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 544, + "width": 209, + "height": 41 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCJKzvudvTus=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 544, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCJNpH+d+vBI=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 648, + "width": 401, + "height": 97 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCJyFDOgUMVg=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 552, + "width": 201, + "height": 25, + "text": "【SERVER】TransMessage" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCJ+wH+ip1tE=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 544, + "width": 393, + "height": 25, + "text": "When,消息产生时间;" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCKW2gOizfRI=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 568, + "width": 393, + "height": 25, + "text": "From,消息发送者ID;" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCLIN3+riI2I=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 544, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCLOol+r+kR0=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 648, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCLV/M+sVeJM=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 111, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCLXuoOskTHA=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;15;0", + "left": 24, + "top": 120, + "width": 145, + "height": 27, + "text": "【发送方】操作名称" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCLbkZus6M2w=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 111, + "width": 401, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCLbkZus78Xk=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;15;0", + "left": 240, + "top": 120, + "width": 257, + "height": 27, + "text": "Head域 请求参数列表" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCLhGTutSdcs=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 111, + "width": 345, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCLhGTutTjgA=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;15;0", + "left": 644, + "top": 119, + "width": 145, + "height": 27, + "text": "Data域,请求数据" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCLouX+uLBdE=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 175, + "width": 401, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCLouX+uMFHQ=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;15;0", + "left": 240, + "top": 184, + "width": 257, + "height": 27, + "text": "Head域 反馈参数列表" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCLouX+uN8K8=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 175, + "width": 345, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCLouX+uOEoA=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;15;0", + "left": 644, + "top": 183, + "width": 145, + "height": 27, + "text": "Data域,反馈数据" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCLs2L+ujcrY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 544, + "width": 337, + "height": 25, + "text": "消息内容数据" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCL1FP+vDJAQ=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 783, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCL1FP+vEWck=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 887, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCL1FP+vFcG4=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 783, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCL1FP+vG6Eo=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 887, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCL1FP+vHvyU=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 783, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCL1FP+vIYdo=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 791, + "width": 209, + "height": 25, + "text": "【CLIENT】SendMessage" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCL/HJ+0bmLY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 784, + "width": 393, + "height": 25, + "text": "To,消息接收者ID;若省略则发送到上一接收对象" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCMCIJu0j+fQ=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 784, + "width": 337, + "height": 25, + "text": "消息内容数据" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCMKEJe0wR3s=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 88, + "width": 75, + "height": 25, + "text": "请求数据:" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCMOW7e1FzZc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 152, + "width": 75, + "height": 25, + "text": "反馈数据:" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNFtCe7IU4k=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 1271, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNFtCe7JFyY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 1375, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNFtCe7KrTY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 1271, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNFtCe7LZvA=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 1375, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNFtCe7MmKI=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 1271, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCNFtCe7NUqs=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 1279, + "width": 209, + "height": 25, + "text": "【CLIENT】Login" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNFtCe7OEHg=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 1272, + "width": 393, + "height": 25, + "text": "User,用户名;" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNI1he7g/Ow=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 1296, + "width": 393, + "height": 25, + "text": "Pwd,密码;" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNQJbe7tzk0=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 1376, + "width": 393, + "height": 25, + "text": "Error,错误文本,登陆成功为空;" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNUJRe78V98=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 2023, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNUJRe79Zm4=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 2128, + "width": 401, + "height": 169 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNUJRe7+nDQ=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 2023, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNUJRe7/QCU=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 2127, + "width": 345, + "height": 170 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCNUJRe8A+UE=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 2023, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCNUJRe8BBVI=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 2031, + "width": 209, + "height": 25, + "text": "【CLIENT】GetUserList" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNUJRe8Eh88=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 2152, + "width": 393, + "height": 25, + "text": "Error,错误文本,成功为空;" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNcftO8eCos=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 2128, + "width": 393, + "height": 25, + "text": "Count,获取到的用户个数;" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNoGre81BBc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 2152, + "width": 337, + "height": 25, + "text": "User,用户名" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNu9de88WCY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 2176, + "width": 337, + "height": 25, + "text": "NickName,昵称" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCNz89+9C904=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 2128, + "width": 337, + "height": 25, + "text": "0...*" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCN5Itu9LpX8=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 2200, + "width": 337, + "height": 25, + "text": "Motto,签名" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCN68ju9RKkc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 2224, + "width": 337, + "height": 25, + "text": "UserGroup,用户组" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCOvQU++gsU0=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;14;0", + "left": 240, + "top": 224, + "width": 323.4619140625, + "height": 26, + "text": "注:有结构的数据皆为json编码数据,[]为可选数据" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCPH85FlGy4g=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 303, + "width": 209, + "height": 42 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCPH85FlH4r0=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 303, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCPH85FlIvME=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 407, + "width": 401, + "height": 97 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnCPH85FlJ4VI=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 28, + "top": 311, + "width": 201, + "height": 25, + "text": "【SERVER】Panic" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCPH85FlKpJE=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 303, + "width": 393, + "height": 25, + "text": "Job,正在执行的操作" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnCPH85FlL00s=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 327, + "width": 393, + "height": 25, + "text": "Error,错误原因" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCPH85FlMK5Y=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 303, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnCPH85FlNvNc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 407, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDNXnP8/e/SY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 244, + "top": 1023, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDNXnP8/fYLM=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 244, + "top": 1127, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDNXnP8/g4Vo=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 644, + "top": 1023, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDNXnP8/hCwA=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 644, + "top": 1127, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDNXnP8/iLT4=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 28, + "top": 1023, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnDNXnP8/jd70=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 28, + "top": 1031, + "width": 209, + "height": 25, + "text": "【CLIENT】Ping" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDc7JK9LgFsc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 241, + "top": 1777, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDc7JK9LhMF4=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 241, + "top": 1881, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDc7JLdLilC8=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 641, + "top": 1777, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDc7JLdLjpxE=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 641, + "top": 1881, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDc7JLdLkks4=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 25, + "top": 1777, + "width": 209, + "height": 41 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDdK1O9TScWI=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 241, + "top": 1526, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDdK1O9TTkCE=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 241, + "top": 1630, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDdK1O9TUhic=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 641, + "top": 1526, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDdK1O9TV4Nc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 641, + "top": 1630, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnDdK1O9TWrIY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 25, + "top": 1526, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnDdK1O9TXGpE=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 25, + "top": 1784, + "width": 209, + "height": 25, + "text": "【SERVER】Offline" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnDdK1O9TYSas=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 241, + "top": 1776, + "width": 393, + "height": 25, + "text": "Error,勒令下线原因" + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnD94Nt6todGc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 24, + "top": 1536, + "width": 209, + "height": 25, + "text": "【Client】Logout" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnD+Va8Ktugac=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 1800, + "width": 393, + "height": 25, + "text": "Addr,新客户端的地址(如果有)" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnD+0dQqt0An8=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 888, + "width": 393, + "height": 25, + "text": "[Error],当NeedResult存在时返回错误内容,成功为空" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnHP4vYMALDPY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 244, + "top": 2426, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnHP4vYMANw0M=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 644, + "top": 2426, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnHQLERFeSNiU=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 112, + "width": 401, + "height": 105 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnHQLERFeTygY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 232, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnHQLERFeUHMU=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1668, + "top": 112, + "width": 345, + "height": 105 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnHQLERFeV5Ts=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1668, + "top": 232, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnHQLERFeWElM=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1052, + "top": 112, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnHQLERFeXiyY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1052, + "top": 119, + "width": 209, + "height": 25, + "text": "【Client】UpdateUserInfo" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHQLERFeYSAk=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 111, + "width": 393, + "height": 25, + "text": "[NickName],新昵称" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnHQRMh1euW+c=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 232, + "width": 393, + "height": 25, + "text": "Error,执行结果,为空则修改成功" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnND+1cMCMi0w=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 136, + "width": 393, + "height": 25, + "text": "[Password],新密码" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNEEGJsCTawo=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 160, + "width": 393, + "height": 25, + "text": "[Motto],新签名" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNEj138eeNg8=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 184, + "width": 393, + "height": 25, + "text": "Photo,头像数据长度" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNEoaOceqiEY=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1668, + "top": 112, + "width": 333, + "height": 25, + "text": "头像数据" + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnNKFIU9KcmRM=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 376, + "width": 401, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnNKFIU9KdW7c=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 481, + "width": 401, + "height": 169 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnNKFIU9KeqfU=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1668, + "top": 376, + "width": 345, + "height": 97 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnNKFIU9Kfz4s=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1668, + "top": 480, + "width": 345, + "height": 170 + }, + { + "_type": "RectangleView", + "_id": "AAAAAAFnNKFIU9Kg3D8=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1052, + "top": 376, + "width": 209, + "height": 41 + }, + { + "_type": "UMLTextView", + "_id": "AAAAAAFnNKFIU9KhQHQ=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1052, + "top": 384, + "width": 209, + "height": 25, + "text": "【CLIENT】GetUserPhoto" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNKFIU9KiVSw=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1268, + "top": 481, + "width": 393, + "height": 25, + "text": "Error,错误文本,成功为空;" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNKFIU9KmUEo=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 1668, + "top": 481, + "width": 337, + "height": 25, + "text": "头像数据" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnNanHBurI4Nc=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 1376, + "width": 329, + "height": 25, + "text": "用户信息(json)" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnq49swuujVy8=", + "_parent": { + "$ref": "AAAAAAFnCJD5xebaqTo=" + }, + "font": "Arial;13;0", + "left": 240, + "top": 808, + "width": 393, + "height": 25, + "text": "[NeedResullt],当此字段*存在*时服务器将返回消息发送结果" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnEWqAz4W4XMc=", + "_parent": { + "$ref": "AAAAAAFm+GxoNtz31qw=" + }, + "name": "UserInfo", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWqu5oXimAI=", + "_parent": { + "$ref": "AAAAAAFnEWqAz4W4XMc=" + }, + "name": "User", + "type": "" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWsfIoXwLj8=", + "_parent": { + "$ref": "AAAAAAFnEWqAz4W4XMc=" + }, + "name": "NickName", + "type": "" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWtJUoX3EUs=", + "_parent": { + "$ref": "AAAAAAFnEWqAz4W4XMc=" + }, + "name": "Motto", + "type": "" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAFnEWrYd4Xp700=", + "_parent": { + "$ref": "AAAAAAFnEWqAz4W4XMc=" + }, + "name": "UGroup", + "type": "" + } + ] + } + ] + }, + { + "_type": "UMLModel", + "_id": "AAAAAAFnp7Q36fVR840=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "client-c#", + "ownedElements": [ + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFnp7RjNPVeQwI=", + "_parent": { + "$ref": "AAAAAAFnp7Q36fVR840=" + }, + "name": "session", + "ownedViews": [ + { + "_type": "UMLClassView", + "_id": "AAAAAAFnp7WMX/V0AOs=", + "_parent": { + "$ref": "AAAAAAFnp7RjNPVeQwI=" + }, + "model": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFnp7WMX/V1gtQ=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V0AOs=" + }, + "model": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFnp7WMX/V20gA=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V1gtQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -368, + "top": -1200, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnp7WMX/V3zv4=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V1gtQ=" + }, + "font": "Arial;13;1", + "left": 237, + "top": 87, + "width": 375, + "height": 13, + "text": "StormClient" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnp7WMX/V4T8M=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V1gtQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -368, + "top": -1200, + "width": 86.67724609375, + "height": 13, + "text": "(from client-c#)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFnp7WMX/V5vG0=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V1gtQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -368, + "top": -1200, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 232, + "top": 80, + "width": 385, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAFnp7WMX/V20gA=" + }, + "nameLabel": { + "$ref": "AAAAAAFnp7WMX/V3zv4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFnp7WMX/V4T8M=" + }, + "propertyLabel": { + "$ref": "AAAAAAFnp7WMX/V5vG0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFnp7WMX/V6Ofo=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V0AOs=" + }, + "model": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "font": "Arial;13;0", + "left": 232, + "top": 105, + "width": 385, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFnp7WMX/V7vnU=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V0AOs=" + }, + "model": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnp768ZPXgGAs=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V7vnU=" + }, + "model": { + "$ref": "AAAAAAFnp768IvXdZko=" + }, + "font": "Arial;13;0", + "left": 237, + "top": 120, + "width": 375, + "height": 13, + "text": "+Initialize()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnp8DSu/Xqv4Y=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V7vnU=" + }, + "model": { + "$ref": "AAAAAAFnp8DShvXnMlE=" + }, + "font": "Arial;13;0", + "left": 237, + "top": 135, + "width": 375, + "height": 13, + "text": "+Login(user: string, pwd: string, callback)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnp8vRtvYSX+I=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V7vnU=" + }, + "model": { + "$ref": "AAAAAAFnp8vRhPYPjkU=" + }, + "font": "Arial;13;0", + "left": 237, + "top": 150, + "width": 375, + "height": 13, + "text": "-send(head: byte, data byte[])", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAFnp8qS+vYK26g=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V7vnU=" + }, + "model": { + "$ref": "AAAAAAFnp8qSxfYHumM=" + }, + "font": "Arial;13;0", + "left": 237, + "top": 165, + "width": 375, + "height": 13, + "text": "-sendData(head: Directory, data: byte)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 232, + "top": 115, + "width": 385, + "height": 68 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAFnp7WMYPV8x54=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V0AOs=" + }, + "model": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -184, + "top": -600, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFnp7WMYPV9V1s=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/V0AOs=" + }, + "model": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -184, + "top": -600, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 232, + "top": 80, + "width": 385, + "height": 264, + "nameCompartment": { + "$ref": "AAAAAAFnp7WMX/V1gtQ=" + }, + "attributeCompartment": { + "$ref": "AAAAAAFnp7WMX/V6Ofo=" + }, + "operationCompartment": { + "$ref": "AAAAAAFnp7WMX/V7vnU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAFnp7WMYPV8x54=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFnp7WMYPV9V1s=" + } + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnp7ZHEfWlEF8=", + "_parent": { + "$ref": "AAAAAAFnp7RjNPVeQwI=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 80, + "width": 401, + "height": 25, + "text": "静态类,负责与服务器的数据交换" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnp73i+PXBgxE=", + "_parent": { + "$ref": "AAAAAAFnp7RjNPVeQwI=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 128, + "width": 401, + "height": 25, + "text": "Initialize(),初始化,连接到服务器" + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnp74wSfXQvNg=", + "_parent": { + "$ref": "AAAAAAFnp7RjNPVeQwI=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 152, + "width": 401, + "height": 25 + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnp8pPovX388s=", + "_parent": { + "$ref": "AAAAAAFnp7RjNPVeQwI=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 224, + "width": 401, + "height": 25 + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnp8pR0fX70iw=", + "_parent": { + "$ref": "AAAAAAFnp7RjNPVeQwI=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 200, + "width": 401, + "height": 25 + }, + { + "_type": "UMLNoteView", + "_id": "AAAAAAFnp8pSsfX/dd8=", + "_parent": { + "$ref": "AAAAAAFnp7RjNPVeQwI=" + }, + "font": "Arial;13;0", + "left": 640, + "top": 176, + "width": 401, + "height": 25 + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAFnp7WMX/VycEU=", + "_parent": { + "$ref": "AAAAAAFnp7Q36fVR840=" + }, + "name": "StormClient", + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAFnp768IvXdZko=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "name": "Initialize" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnp8DShvXnMlE=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "name": "Login", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnp8FQqfXuyEU=", + "_parent": { + "$ref": "AAAAAAFnp8DShvXnMlE=" + }, + "name": "user", + "type": "string" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnp8FQqvXv45c=", + "_parent": { + "$ref": "AAAAAAFnp8DShvXnMlE=" + }, + "name": "pwd", + "type": "string" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnp8HDPvXzyKo=", + "_parent": { + "$ref": "AAAAAAFnp8DShvXnMlE=" + }, + "name": "callback", + "type": "" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnp8vRhPYPjkU=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "name": "send", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnp8xaYPYXzF8=", + "_parent": { + "$ref": "AAAAAAFnp8vRhPYPjkU=" + }, + "name": "head", + "type": "byte" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnp8xaYPYYnrY=", + "_parent": { + "$ref": "AAAAAAFnp8vRhPYPjkU=" + }, + "name": "data byte[]", + "type": "" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnp8qSxfYHumM=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "name": "sendData", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAFnp86VW/YfR8M=", + "_parent": { + "$ref": "AAAAAAFnp8qSxfYHumM=" + }, + "name": "head", + "type": "Directory" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAFnp86VW/YgHt8=", + "_parent": { + "$ref": "AAAAAAFnp8qSxfYHumM=" + }, + "name": "data", + "type": "byte" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAFnrTf5eu1XwoM=", + "_parent": { + "$ref": "AAAAAAFnp7WMX/VycEU=" + }, + "name": "Operation1" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/stormchat-client/res/conctrl_x64.dll b/stormchat-client/res/conctrl_x64.dll new file mode 100644 index 0000000000000000000000000000000000000000..066629793d0c0d8b1d1447feb80f4e1ab61529cd GIT binary patch literal 32256 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 literal 0 HcmV?d00001 diff --git a/stormchat-client/src/control.go b/stormchat-client/src/control.go new file mode 100644 index 0000000..3f4d130 --- /dev/null +++ b/stormchat-client/src/control.go @@ -0,0 +1,60 @@ +package main + +//宏 +const ( + //最大包头长度 + max_head_length uint32 = 4096 //4K + //最大消息长度 + max_message_length uint32 = 0x6400000 //64M + //最大头像大小 + max_photo_size uint32 = 0x400000 //4M + //服务器地址 + server_addr string = "mattuy.top:3727" +) + +//用户组 +const ( + ugroup_user string = "User" //普通用户 + ugroup_vip string = "Vip" //会员 + ugroup_admin string = "Admin" //管理员 + ugroup_group string = "Group" //群聊 +) + +//消息头的通用字段名称 +const ( + keyname_operation string = "Operation" //操作名 + keyname_token string = "Token" +) + +//控制消息 +const ( + operation_panic string = "Panic" + operation_trans_message string = "TransMessage" + operation_send_message string = "SendMessage" + operation_ping string = "Ping" + operation_login string = "Login" + operation_logout string = "Logout" + operation_offline string = "Offline" + operation_get_user_list string = "GetUserList" + operation_update_userinfo string = "UpdateUserInfo" +) + +//帮助 +const help_message string = ` + 欢迎使用StormChat! + 输入“help”查看命令列表 + 输入“.”退出命令模式,退出后可输入“.”重新进入命令模式 + 聊天时可在行末输入‘\’以换行输入消息 +` + +//指令列表 +const command_list string = ` + 指令列表: + . 退出命令模式 login 登录 + to 设定聊天对象 logout 注销 + friends 查看用户列表 help 显示命令列表 + scroll 消息面板翻页 clear 清空消息记录 + exit 退出程序 + CTRL + C 强制退出 + +` diff --git a/stormchat-client/src/main.go b/stormchat-client/src/main.go new file mode 100644 index 0000000..37a0b63 --- /dev/null +++ b/stormchat-client/src/main.go @@ -0,0 +1,256 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" + "time" +) + +/* +#include +#include +int getkey() { + return getch(); +} +*/ +import "C" + +var commandMode bool //指示当前是否处于命令模式 +func main() { + defer func() { + fmt.Print("按任意键退出程序") + C.getkey() + DestroyConsoleWindow() + }() + InitConsole() + client := NewSession() + if client == nil { + return + } + SetUserNameText("未登录") + SetCurrentFriendText("") + PrintInfo(help_message) + if len(os.Args) >= 3 { + client.Login(os.Args[1], os.Args[2]) + commandMode = false + } + commandMode = true + PrintInfo(command_list) + if InputCommand(client) { + return + } + var message string + var input string + for { + if message == "" { + ClearInput() + } + reader := bufio.NewReader(os.Stdin) + input, _ = reader.ReadString('\n') + input = strings.TrimSuffix(input, "\r\n") + input = strings.TrimSuffix(input, "\n") + switch input { + case ".": + message = "" + if InputCommand(client) { + return + } + case ".quit": + return + case ".exit": + return + default: + message += input + if strings.HasSuffix(input, "\\") { + message = strings.TrimSuffix(message, "\\") + message += "\r\n" + } else { + client.SendMessage([]byte(message)) + message = "" + } //发送成功,清空消息缓存 + } + } +} + +//输入指令 +func InputCommand(client *Session) bool { + defer SetOperationText("聊天") + SetOperationText("命令模式") + for { + ClearInput() + var input string + reader := bufio.NewReader(os.Stdin) + input, _ = reader.ReadString('\n') + input = strings.TrimSuffix(input, "\r\n") + input = strings.TrimSuffix(input, "\n") + switch strings.TrimRight(input, " ") { + case "scroll": + ScrollMessage() + case "login": + success := LoginWithInput(client) + if !success { + client.destroy() + client = NewSession() + PrintError("登录失败,请重试。") + } //如果连接已中断则重新创建session + case "logout": + client.Logout() + case "to": + SwitchReceiver(client) + case "friends": + ViewFriends(client) + case "clear": + ClearOutput() + case "help": + PrintInfo(command_list) + case ".": + return false + case "exit": + return true + default: + PrintError("无效命令") + } + } +} + +//发起登录。如果返回值为false则session已失效(根据发送数据失败判断) +func LoginWithInput(session *Session) bool { + SetOperationText("登录") + defer func() { + if commandMode { + SetOperationText("命令模式") + } else { + SetOperationText("聊天") + } + }() + if session.status == session_status_running { + PrintError("已经登录,请先注销。") + return true //虽然登录失败但连接仍有效,因此返回true + } + reader := bufio.NewReader(os.Stdin) + PrintInputTip("user: ") + user, _ := reader.ReadString('\n') + user = strings.TrimSuffix(user, "\r\n") + user = strings.TrimSuffix(user, "\n") + PrintInputTip("password: ") + pwd, _ := reader.ReadString('\n') + pwd = strings.TrimSuffix(pwd, "\r\n") + pwd = strings.TrimSuffix(pwd, "\n") + if !session.Login(user, pwd) { + return false + } + return true +} + +//更换聊天对象 +func SwitchReceiver(session *Session) { + if session.status != session_status_running { + PrintError("请先登录") + return + } + SetOperationText("切换好友") + PrintInputTip("好友ID或昵称(输入*启用广播模式): ") + var found bool = false //好友是否存在 + var friend string + reader := bufio.NewReader(os.Stdin) + friend, _ = reader.ReadString('\n') + friend = strings.TrimSuffix(friend, "\r\n") + friend = strings.TrimSuffix(friend, "\n") + if friend == "*" { + SetCurrentFriendText("广播模式") + session.receiver = friend + } //广播消息 + //查询好友列表 + for _, item := range session.friends { + if strings.ToLower(item.NickName) == strings.ToLower(friend) || item.User == friend { + SetCurrentFriendText(item.NickName) + session.receiver = item.User + found = true + break + } + } + if commandMode { + SetOperationText("命令模式") + } else { + SetOperationText("聊天") + } + if !found { + PrintError("未找到名为【" + friend + "】的好友") + } +} + +//查看好友列表 +func ViewFriends(session *Session) { + list := session.friends + if session.status != session_status_running { + PrintError("请先登录") + return + } + if len(list) == 0 { + PrintInfo("好友列表为空") + return + } + for _, item := range list { + PrintInfo(item.User + " " + item.NickName) + } +} + +//滚动消息面板 +func ScrollMessage() { + if commandMode { + defer SetOperationText("命令模式") + } else { + defer SetOperationText("聊天") + } + defer ClearInput() + SetOperationText("翻页模式") + PrintInputTip("上翻:P\n下翻:N\n退出翻页:ESC\n") + for { + key := C.getkey() + switch key { + case 'p': + ScrollOutputArea(-1) + case 'n': + ScrollOutputArea(1) + case 27: + return + } + } +} + +//输出错误 +func PrintError(err string) { + PrintOutputLine("[ERROR] "+err, FOREGROUND_RED) +} + +//输出信息 +func PrintInfo(text string) { + PrintOutputLine(text, FOREGROUND_RED|FOREGROUND_GREEN) +} +func PrintLog(str string) { + PrintOutputLine("[INFO] "+str, FOREGROUND_INTENSITY) +} + +//输出消息头 +func PrintMessageHead(head string, intensity bool) { + if intensity { + PrintOutputLine(head, FOREGROUND_INTENSITY) + } else { + PrintOutputLine(head, FOREGROUND_GREEN) + } +} + +//输出消息体 +func PrintMessage(msg string) { + PrintOutputLine(msg, FORGROUND_WHITE) +} + +//构造消息头 +func MakeHead(operation string) map[string]string { + headInfo := make(map[string]string) + headInfo[keyname_token] = string(time.Now().UnixNano()) + headInfo[keyname_operation] = operation + return headInfo +} diff --git a/stormchat-client/src/session.go b/stormchat-client/src/session.go new file mode 100644 index 0000000..75cb5b5 --- /dev/null +++ b/stormchat-client/src/session.go @@ -0,0 +1,324 @@ +package main + +import ( + "encoding/binary" + "encoding/json" + "net" + "sync/atomic" + "time" +) + +//当前session的状态 +const ( + session_status_created = iota //已创建,但未登录 + session_status_running // 通道已建立,session正常运行 + session_status_stoped // 标识连接已断开 + session_status_destroyed +) + +type Session struct { + sender *UserInfo //消息发送者 + receiver string //消息接收者 + friends []UserInfo //好友列表 + conn *net.TCPConn //TCP连接 + status int32 //session运行状态 + stopChan chan bool //Session终止标识,传递数据即终止。仅由读消息循环用于终止写循环 + writeCh chan []byte //写消息通道 + writeResultCh chan bool //是否写成功 +} + +//初始化 +func NewSession() *Session { + tcpAddr, _ := net.ResolveTCPAddr("tcp", server_addr) + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + PrintError("连接服务器失败") + return nil + } + var session = new(Session) + session.sender = nil + session.receiver = "" + session.status = session_status_created + session.stopChan = make(chan bool) + session.writeCh = make(chan []byte) + session.writeResultCh = make(chan bool) + session.conn = conn + go session.SendLoop() + go session.ReceiveLoop() + return session +} + +//销毁聊天连接 +func (session *Session) destroy() { + if session.status == session_status_destroyed { + return + } + session.status = session_status_destroyed + session.conn.Close() + close(session.writeCh) + close(session.writeResultCh) +} + +//消息写循环 +func (session *Session) SendLoop() { + defer session.destroy() + for { + select { + case data, ok := <-session.writeCh: + if !ok { + atomic.SwapInt32(&session.status, session_status_stoped) + continue + } + writeLen, err := session.conn.Write(data) + if err != nil || (writeLen != len(data)) { + PrintError(err.Error()) + atomic.SwapInt32(&session.status, session_status_stoped) + session.writeResultCh <- false + } //写失败 + session.writeResultCh <- true + case <-session.stopChan: + return + } + } +} + +//消息读循环 +func (session *Session) ReceiveLoop() { + defer func() { + session.stopChan <- true + }() //终止写循环 + var err error //错误 + for { + if atomic.LoadInt32(&session.status) >= session_status_stoped { + return + } //检查session是否已终止 + //读取数据 + head := session.readDataWithLength() + data := session.readDataWithLength() + + if head == nil || data == nil { + PrintError("获取数据失败") + atomic.SwapInt32(&session.status, session_status_stoped) + continue + } + //解析包头 + headInfo := make(map[string]string) + err = json.Unmarshal(head, &headInfo) + if err != nil { + PrintError("解析包头失败") + continue + } + switch headInfo[keyname_operation] { + case operation_send_message: + session.ResultHandler(headInfo) + break + case operation_update_userinfo: + session.ResultHandler(headInfo) + break + case operation_offline: + case operation_panic: + session.PanicHandler(headInfo) + break + case operation_login: + session.LoginDoneHandler(headInfo, data) + break + case operation_trans_message: + session.MessageHandler(headInfo, data) + break + case operation_get_user_list: + session.GetUserListHandler(headInfo, data) + break + default: + continue + } + } +} + +//处理请求结果反馈消息 +func (session *Session) ResultHandler(headInfo map[string]string) { + if headInfo["Error"] == "" { + PrintLog(headInfo[keyname_operation] + " successfully.") + } else { + PrintError("Failed to " + headInfo[keyname_operation] + ": " + headInfo["Error"]) + } +} + +//服务器报错 +func (session *Session) PanicHandler(headInfo map[string]string) { + PrintError("Server Error: " + headInfo["Error"]) + atomic.SwapInt32(&session.status, session_status_stoped) +} + +//登录反馈 +func (session *Session) LoginDoneHandler(headInfo map[string]string, data []byte) { + session.ResultHandler(headInfo) + if headInfo["Error"] == "" { + user := new(UserInfo) + err := json.Unmarshal(data, user) + if err != nil { + PrintError("解析用户信息失败") + return + } else { + session.sender = user + SetUserNameText(user.NickName) + } + atomic.SwapInt32(&session.status, session_status_running) + session.GetUserList() + } +} + +//获取用户列表 +func (session *Session) GetUserListHandler(headInfo map[string]string, data []byte) { + session.ResultHandler(headInfo) + if headInfo["Error"] != "" { + return + } + err := json.Unmarshal(data, &session.friends) + if err != nil { + PrintError("解析用户信息失败: " + err.Error()) + } +} + +//输出消息 +func (session *Session) MessageHandler(headInfo map[string]string, message []byte) { + if headInfo["Error"] != "" { + PrintError("发送消息失败: " + headInfo["Error"]) + return + } + var user *UserInfo = nil + for _, item := range session.friends { + if item.User == headInfo["From"] { + user = &item + break + } + } + when, _ := time.Parse(time.RFC3339, headInfo["When"]) + if user == nil { + PrintMessageHead(headInfo["From"]+" ["+when.Format("2006-01-02 15:04:05")+"]", false) + } else { + PrintMessageHead(user.NickName+" ["+when.Format("2006-01-02 15:04:05")+"]", false) + } + PrintMessage(string(message)) + if session.receiver == "" && user != nil { + session.receiver = user.User + SetCurrentFriendText(user.NickName) + } //如果无当前聊天对象则将聊天对象设置为消息发送者 +} + +//发送数据 +func (session *Session) send(head []byte, data []byte) bool { + if atomic.LoadInt32(&session.status) >= session_status_stoped { + return false + } + var buf = make([]byte, 4) //长度标识 + var packet = make([]byte, 0, len(head)+len(data)+4+4) //headLen + head + msgLen + data + //写包头 + //取包头长 + binary.BigEndian.PutUint32(buf[0:4], uint32(len(head))) + packet = append(packet, buf...) //写包头长度 + if len(head) > 0 { + packet = append(packet, head...) //写包头 + } + //写数据 + //取数据长 + binary.BigEndian.PutUint32(buf[0:4], uint32(len(data))) + packet = append(packet, buf...) //写数据长度 + if len(data) > 0 { + packet = append(packet, data...) //写数据 + } + + if len(packet) != cap(packet) { + return false + } //数据异常 + if atomic.LoadInt32(&session.status) >= session_status_stoped { + return false + } + session.writeCh <- packet + return <-session.writeResultCh +} + +//读取数据 +func (session *Session) readDataWithLength() []byte { + var dataLen uint32 //数据长度 + var lenBuffer [4]byte //数据长度缓存区 + var data []byte //数据缓存区 + //获取数据长度 + readedLen, err := session.conn.Read(lenBuffer[0:4]) + if err != nil || readedLen != 4 { + PrintError("获取消息失败。 Error: " + err.Error()) + return nil + } + dataLen = binary.BigEndian.Uint32(lenBuffer[0:4]) + data = make([]byte, dataLen) + if dataLen == 0 { + return data + } + readedLen, err = session.conn.Read(data) + if err != nil || readedLen != int(dataLen) { + PrintError("获取消息失败。Error:" + err.Error()) + return nil + } + return data +} + +//发送数据 +func (session *Session) SendData(headInfo map[string]string, data []byte) bool { + head, err := json.Marshal(headInfo) + if err != nil { + PrintError("Marshal Failed.") + return false + } + return session.send(head, data) +} + +//发送消息 +func (session *Session) SendMessage(msg []byte) bool { + if session.sender == nil { + PrintError("请先登录") + return false + } + if session.receiver == "" { + PrintError("请先设定当前聊天好友") + return false + } + if len(msg) == 0 { + PrintError("无法发送空消息") + return false + } + PrintMessageHead(session.sender.NickName+" ["+time.Now().Format("2006-01-02 15:04:05")+"]", true) + PrintMessage(string(msg)) + headInfo := MakeHead(operation_send_message) + headInfo["To"] = session.receiver + return session.SendData(headInfo, msg) +} + +//登录 +func (session *Session) Login(user string, pwd string) bool { + logInfo := MakeHead(operation_login) + logInfo["User"] = user + logInfo["Pwd"] = pwd + return session.SendData(logInfo, nil) +} + +//请求登出 +func (session *Session) Logout() { + if session.sender == nil { + PrintError("当前未登录") + return + } //未登录 + headInfo := MakeHead(operation_logout) + session.SendData(headInfo, nil) + atomic.SwapInt32(&session.status, session_status_created) + session.sender = nil + session.friends = nil + session.receiver = "" + SetUserNameText("未登录") + SetCurrentFriendText("") + PrintLog("已登出.") +} + +//获取好友列表 +func (session *Session) GetUserList() { + headInfo := MakeHead(operation_get_user_list) + session.SendData(headInfo, nil) +} diff --git a/stormchat-client/src/stormchat-client.syso b/stormchat-client/src/stormchat-client.syso new file mode 100644 index 0000000000000000000000000000000000000000..019e492c153d997109a8749c63b8cbed4cc21289 GIT binary patch literal 9954 zcmeHN2Xs`|nZ9p&lctX}qmf3vmywWAN2pL_fj}UHM3c~{_uhN&qfwVI)y4)+HYPca zZ3uBVv2$$fBqVmQottR@jbbqjcv5V&PEEA9RgtS>A z-;5mDKb)t`_YZl%JfB6#A$l>kd-tQUwBaxB3)Y{+^I{TD;*ipjV#y|wh`m^{0Y_`F zpG?l;nqw|_SZ;ZUUvY1M+#N}elz~Li$m!-xNR@1fmL{GYpJ?Fm)WENQahbe}^xiK& zq~8DKhlHlbrL}h-BqOHhlt-R@MR)Q2-*ex2_1t5Fe_-$kdHc;XR9(|taCP0`qOtK) zn!({09}Cr|W_6IQ8O@xH+uQ9M+nx<5C^<5nwtJ$xt>*}{we$ERD??q|3ubI9!rP^5 zH+06VifjEzXxQM9u&{yIb@BZ_%E}oPmscHlWbtPiOr$VxMCjyReo$%O@{vdI=yezG zPH=FpgMfgl9vXOm|B{T4q7YfR!^Du&YZ)9~KNA@=_5YfXbte&Q*7`x`suuy#6+WU$w}$EV;QNs5X-Z z|JoamRt(L`8zVV+!efZ_Iy_#(Dss0ln0K^1+Q1v z%*b=|#~-OZ$jmV!{vnx_uJBF5F9RZK1*W_YIO+kgui|m714PgX3_&gEoNC`p-Ztg#=G{t8 z96$H1@4baJc3HId9r+9S=0ej(gI9H3$W$2z?PH)$FdYGWThBC zTR^L81qQnmn7kaYcQqWpbonjT;Kv>TO(E(ZV+}c5NjS>uber{?iqaU8^@oSZz6^Q6L;;VZqN9nQQhXG zjz}MU;Y-eLWeYN8Ij{wlKsXIZT|n`NfN41bY|9~F2-{Kj#UQjyhtSB1UK;qsxI!nU+Ih+ESOKEBnUbF2iVRW;&m02aRu zeYqPbP6zfIK&`I17#iA?YA6`tZBFj`W@TV)CH}$X1wvWDUBa)&SlIzY)(s5nK@i#x zgSE#HxcK+Oitr&=pJ0O29W#FokL>!l@JQpS=(SJZky^C_VON4sl5@jTUtC3lf9B{L zU#kp>sH3u)S#C;Nx2mRYNE{Q_loPh9_ubIQad5=gB2fze0XJnG+%itD~>Wt$I#wFmcN57;_o9S6A0oSHlHwc$@p>LiBjQMrq6 z#hBc-;60Vy?l%<5)N3M9`W+j)I&k+IgrJap5FGYAXzllbKsJdsKaH_y8spG3u;i0K zNe6(kXaR~_2n^0n^x;hyU*o~WYgYpe{NxYMe=Ydu_AS+l?tVo*JbCe5$^vtexE>gi zN?=$N0>#TP>ygRL29cy1kfsYZb-8U_X*V-VkndCLTp(1bY*Ill*(T=WNSG4L(- zEb0Txt1$;K+Xv`3F<(u)ms6%@o@3<~b&ASLTErodwWT6?`Co|u{5uF(v=904W(`q_FCcMMzB39&4BU6Ee-#pGp-Q&dIG)-sTCDZ!%ENl-Xx{fs%{? zWjzBd2ecWt10ZnO2VBQ7;MjCx?Nf>Nf_5(0i#ZGBVHY7@l#$bHCW_sN`&I`Os~EWA z^t*n6`T2xI|4aBMr(ZSab5H;37E9~mTMTJ2P~u$Fs{t6IEMW4}(QbF5Uehsllw&>6 zhB+4PT8jH%HHUtC7}!onfbD!3Sh}ZyVKWYtvIp-`gEbJ^8pnWm_nL{t%>_2*VHPI? zYm8Lz(i_SN!MB3{kCvTfBqhZY%!rtJTfdOX5NCbCdat08P2Pd^C-|~r#9aqOg8M9O zL7PWiSymub0UP^j$9C{rISgKY!yv=_%H&|Zi8jIzp|6S$0z+{CW6^$KsOErDO#vlC zKR~-<2(ZTB6oTBU0DSx^VMS2Eg^=*9q4@dHZ?(#Sds*GxQ;~`IefTi+rn$ z>vry0w_Sbm7P!*nJJxn-5D?S~5=|TacR%7me^d-&oJW01JFq@z2ezUUgf{&kv~CBE zMK$hAp&1*KgTBqjHMIWoF07o+fe9Z`Otp|W5YXhdJ67dx+$-*u{f33kW z)^7Yhvky}|v^mVh3|}hgT7E= zjz1I|eVT`T;T}-xw!fF2-K0rPZ+syBKI1W-+CJ~3r6TRBlV?(ef9Rf=@Yr1UsMtm) zSHIRmm0inufueCyW!Et8?$cz9UDq4$8_=~&ZC`UtEHC+3t1CsDs=Mvrm~&2|%zay| zuKh@C+y6P=b^_SwuT0y6z*Nrwr5Ht9N1L#!jwAd!y=`UMFKlI!8s3 zEnDYwE*^a&GHu@_p{nb1m3`MQT)g{BSI3R7*pj?I*2jNfz)L^$T2S!N_f`b=bVSE= zm4=2^H#xeNP2jtd7o|GW2Lj#nb*}B)BFkzYJ_q2wU~Hnq7;A-SKltpzLVIEIF%EDr zKG1S-wt-Ndcs)EOcLO1g|L5}z?XM0VW#cRX#y)w+H4pt*b5Z3B5}lWcEZqEe(l_t| zIsNia8Ec-JaPSHo$=0|HzAe%Wd~RVg@*is5&<|Dyj}>lDJLnq~JsPQBIasXsAAZKg zz5k4>_rSr(n2E}bnP^zCg?;n(2l2<;e^a;r#7cX7?r#k! zr}dHhw{6+EUlOr?(tOR&&i~G=haKs&YVV-Y6dU)k19IE3OLAM&XG)#vw_2C+{oX4k zGvYVRMn$iki1!UN7J3C3XE2r?^Y$G)s9!PE6&f+JH#*L^BP4tv*WJ5sKx5bWl339` z&$Vn@ptu;*=z3bv1WWgE@0e$8^940L?b>PkpLV!wmE zL;Xu!QTqZN&n)E4xBUYe3@mQ?ee3B#W9<<#GkTnvkT|CeiJCOnx(=U~+D`sSqMccg z+KztW>}5I~7(SaHy?$TtmXrhT@f&AX#;%<%^z!Y0*50)X_onmJh*blJqGAUdBUW`+ zM6PQ2j*n0EZ3{8xadTeAn8C>f4&MMWb>0oR&5mm;BMiHR(zt)ZLQhbG%{OpnyQ9aHN$WiEE8Lr# zmYVVFD*K6d>|7_F@${W2PfR+vCa37Q$5V;ZK4FoA2?0U9`M&-=9f2!5r()uIU-$B@ zxva9zxGs~Y+~#oBEpm8q;O3M0Va&S9qN3sfafYGe3$f5AP8@&Dj3+U%)AOnL7CpT; zKmR!`+m~zK`~E4iaO*r(UiDo~SkzRKqo=7?>o9&wuAR6du^PRh(wVMnoW{@ToK5@O zd`F9e!zb4zY@GJoo4H?I*K|x>S$o`V=WbJI!iLs3SGPU&V(I!1nEa?kORI!yuKv55 zzW73>$Q20cYK4hxO+0*#4Ox-naY1RAR5>?-4 za_hdoD6Bg#*xGfR^784PjfyqpheZv=u3p!#U$eG8#agrJGT}x8M-dOM`rSr4KF%F} z`Qd>*^xw}O{=q|{`06kF{k8Kb*B_{kuA|(YJ13+` zDJF-MZKM9l$)mBGHV-8vCk;nz-Q4F`kT=e!?fJhxzWLRIcyh-l8hE0CCmML7fyYh* zm=ox&gB64iTH@?-1^Ne13U; zo-obx_c(sPM2{EA(mZnW_)}ChJ%4tYw=MBo$mn_cG-+M_z$)tRoSw$VGQy=fu4A?> zjoapt>j*h}XNk|_IePpl;GM*{lm>top^^}&nM2z$2V84b-$QWv>nw`s^-EuA(O+~? ZfBRmHNlqdNx-swjZjJtaj7eB{{2$9wLWuwX literal 0 HcmV?d00001 diff --git a/stormchat-client/src/user.go b/stormchat-client/src/user.go new file mode 100644 index 0000000..5ef4848 --- /dev/null +++ b/stormchat-client/src/user.go @@ -0,0 +1,9 @@ +package main + +//用户信息 +type UserInfo struct { + User string //用户名 + NickName string //昵称 + Motto string //签名 + UGroup string //用户组。ugroup_*常量值 +} diff --git a/stormchat-client/src/win-console.go b/stormchat-client/src/win-console.go new file mode 100644 index 0000000..7edadb7 --- /dev/null +++ b/stormchat-client/src/win-console.go @@ -0,0 +1,158 @@ +package main + +import ( + "math" + "strings" + "syscall" + "unsafe" +) + +const ( + FOREGROUND_BLUE int = 1 + FOREGROUND_GREEN int = 2 + FOREGROUND_RED int = 4 + FOREGROUND_INTENSITY int = 8 + BACKGROUND_BLUE int = 16 + BACKGROUND_GREEN int = 32 + BACKGROUND_RED int = 64 + BACKGROUND_INTENSITY int = 128 + + FORGROUND_WHITE int = 7 +) + +var conctrl *syscall.LazyDLL //Windows控制台窗口辅助输出库 +var consoleWindow uintptr //控制台窗口控制器指针 +var messagePannel uintptr //消息输出窗格 +var operationPannel uintptr //操作提示窗格 +var usrenamePannel uintptr //用户名显示窗格 +var currentFriendPannel uintptr //当前聊天对象显示窗格 +var inputPannel uintptr //输入窗格 +var spliter uintptr //分割线 +//初始化 +func InitConsole() { + conctrl = syscall.NewLazyDLL("conctrl_x64.dll") + proc := conctrl.NewProc("CreateConsoleWindow") + consoleWindow, _, _ = proc.Call(100, 999) + if consoleWindow == 0 { + panic("Failed to init console. conctrl.dll not found.") + } + proc = conctrl.NewProc("CreatePannel") + messagePannel, _, _ = proc.Call(consoleWindow, 0, 0, 100, 20) + operationPannel, _, _ = proc.Call(consoleWindow, 0, 21, 20, 1) + usrenamePannel, _, _ = proc.Call(consoleWindow, 35, 21, 30, 1) + currentFriendPannel, _, _ = proc.Call(consoleWindow, 65, 21, 35, 1) + inputPannel, _, _ = proc.Call(consoleWindow, 0, 23, 100, 20) + proc = conctrl.NewProc("CreateSpliter") + spliter, _, _ = proc.Call(consoleWindow, 0, 22, 100, 0, uintptr(FORGROUND_WHITE)) + proc = conctrl.NewProc("FocusOnPannel") + proc.Call(inputPannel, 0, 0) + SetTitle("StormChat") +} + +//滚动输出区域 +func ScrollOutputArea(lineCount int) { + var proc *syscall.LazyProc + if lineCount > 0 { + proc = conctrl.NewProc("ScrollPannelForward") + } else { + proc = conctrl.NewProc("ScrollPannelBackward") + } + proc.Call(messagePannel, uintptr(math.Abs(float64(lineCount)))) +} + +//设置控制台标题 +func SetTitle(title string) { + proc := conctrl.NewProc("SetConsoleWindowTitle") + titleB := append([]byte(title), 0) + pTtile := *(*uintptr)(unsafe.Pointer(&titleB)) + proc.Call(uintptr(pTtile), 1) +} + +//设置当前操作提示文本 +func SetOperationText(op string) { + proc := conctrl.NewProc("ClearPannel") + proc.Call(operationPannel) + AddPannelLine(operationPannel, op, false, FORGROUND_WHITE) +} + +//设置用户昵称显示区文本 +func SetUserNameText(name string) { + blank := (30 - len(name)) / 2 + if blank > 0 { + name = strings.Repeat(" ", blank) + name + } + proc := conctrl.NewProc("ClearPannel") + proc.Call(usrenamePannel) + AddPannelLine(usrenamePannel, name, false, FORGROUND_WHITE) +} + +//设置当前聊天好友提示文本 +func SetCurrentFriendText(friend string) { + if friend != "" { + friend = "To: " + friend + } + blank := 34 - len(friend) + if blank > 0 { + friend = strings.Repeat(" ", blank) + friend + } + proc := conctrl.NewProc("ClearPannel") + proc.Call(currentFriendPannel) + AddPannelLine(currentFriendPannel, friend, false, FORGROUND_WHITE) +} + +//向输出区写行 +func PrintOutputLine(text string, attribute int) { + AddPannelLine(messagePannel, text, false, attribute) +} + +//向输入区写文本 +func PrintInputTip(text string) { + ClearInput() + AddPannelText(inputPannel, text, true, FORGROUND_WHITE) +} + +//清空输入区 +func ClearInput() { + proc := conctrl.NewProc("ClearPannel") + proc.Call(inputPannel) + proc = conctrl.NewProc("FocusOnPannel") + proc.Call(inputPannel, 0, 0) +} + +func ClearOutput() { + proc := conctrl.NewProc("ClearPannel") + proc.Call(messagePannel) +} + +//销毁控制器,恢复控制台 +func DestroyConsoleWindow() { + proc := conctrl.NewProc("FocusOnPannel") + proc.Call(messagePannel, 0, 0) + proc = conctrl.NewProc("DestroyConsoleWindow") + proc.Call(consoleWindow) +} + +//向窗格加入文本行 +func AddPannelLine(pannel uintptr, text string, focus bool, attribute int) { + proc := conctrl.NewProc("AddPannelLine") + addPannel(proc, pannel, text, focus, attribute) +} + +//向窗格加入文本 +func AddPannelText(pannel uintptr, text string, focus bool, attribute int) { + proc := conctrl.NewProc("AddPannelText") + addPannel(proc, pannel, text, focus, attribute) +} + +//向窗格加入文本(行) +func addPannel(proc *syscall.LazyProc, pannel uintptr, text string, focus bool, attribute int) { + line := append([]byte(text), 0) + pLine := *(*uintptr)(unsafe.Pointer(&line)) + var focusInt int + if focus { + focusInt = 1 + } else { + focusInt = 0 + } + proc.Call(pannel, uintptr(pLine), uintptr(focusInt), 1, uintptr(attribute)) +} diff --git a/stormchat-server/res/stormchat.sql b/stormchat-server/res/stormchat.sql new file mode 100644 index 0000000..ee80079 --- /dev/null +++ b/stormchat-server/res/stormchat.sql @@ -0,0 +1,28 @@ +DROP TABLE IF EXISTS `message`; +CREATE TABLE `message` ( + `Id` int(11) NOT NULL AUTO_INCREMENT, + `When` varchar(44) NOT NULL, + `From` varchar(12) NOT NULL, + `To` varchar(12) NOT NULL, + `Msg` text, + PRIMARY KEY (`Id`) +) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +LOCK TABLES `message` WRITE; +UNLOCK TABLES; + +DROP TABLE IF EXISTS `user`; +CREATE TABLE `user` ( + `User` varchar(12) NOT NULL, + `Pwd` varchar(16) NOT NULL, + `NickName` varchar(36) NOT NULL DEFAULT '', + `Motto` varchar(144) NOT NULL DEFAULT '', + `UGroup` enum('User','Vip','Admin','Group') DEFAULT 'User', + `Photo` mediumtext, + PRIMARY KEY (`User`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +LOCK TABLES `user` WRITE; +INSERT INTO `user` VALUES ('mattuy','mattuy','Mattuy','','Admin',NULL); +UNLOCK TABLES; + diff --git a/stormchat-server/src/stormchat/control.go b/stormchat-server/src/stormchat/control.go new file mode 100644 index 0000000..100dfec --- /dev/null +++ b/stormchat-server/src/stormchat/control.go @@ -0,0 +1,72 @@ +package main + +//宏 +const ( + //是否为服务模式,调试时置为false以输出调试信息 + serveMode = false + //最大包头长度 + max_head_length uint32 = 4096 //4K + //最大消息长度 + max_message_length uint32 = 0x6400000 //64M + //最大头像大小 + max_photo_size uint32 = 0x400000 //4M + //最大数据等待时间,单位秒。客户端应发送心跳包以保持连接。调试,先设为100年 + timeout_message = 100 * 365 * 24 * 60 * 60 +) + +//用户组 +const ( + ugroup_user string = "User" //普通用户 + ugroup_vip string = "Vip" //会员 + ugroup_admin string = "Admin" //管理员 + ugroup_group string = "Group" //群聊 +) + +//消息头的通用字段名称 +const ( + keyname_operation string = "Operation" //操作名 + keyname_token string = "Token" +) + +//控制消息 +const ( + operation_panic string = "Panic" + operation_trans_message string = "TransMessage" + operation_send_message string = "SendMessage" + operation_ping string = "Ping" + operation_login string = "Login" + operation_logout string = "Logout" + operation_offline string = "Offline" + operation_get_user_list string = "GetUserList" + operation_update_userinfo string = "UpdateUserInfo" +) + +//字符串常量 +const ( + //日志文件。交互模式时无效(输出到os.Stdout) + str_log_file string = "/var/log/stormchat.log" + //mysql连接字符串 + str_db_conn_str string = "stormchat:stormchat@tcp(localhost:3306)/stormchat?charset=utf8" + //登陆 + str_sql_login string = "SELECT `User`, `NickName`, `Motto`, `UGroup` FROM `user` WHERE `User`=? AND `Pwd`=? LIMIT 1" + //获取用户信息 + str_sql_query_user string = "SELECT `User`, `NickName`, `Motto`, `UGroup` FROM `user` WHERE `User`=? LIMIT 1" + //获取头像 + str_sql_get_photo string = "SELECT `Photo` FROM `user` WHERE `User`=?" + //设置昵称 + str_sql_update_nickname string = "UPDATE `user` SET `NickName`=? WHERE `User`=?" + //设置密码 + str_sql_update_password string = "UPDATE `user` SET `Pwd`=? WHERE `User`=?" + //设置签名 + str_sql_update_motto string = "UPDATE `user` SET `Motto`=? WHERE `User`=?" + //设置头像 + str_sql_update_photo string = "UPDATE `user` SET `Photo`=? WHERE `User`=?" + //获取用户列表(有序) + str_sql_get_users string = "SELECT `User`, `NickName`, `Motto`, `UGroup` FROM `user` ORDER BY `User`" + //SQL语句-消息入库 + str_sql_save_message string = "INSERT INTO `message` (`When`, `From`, `To`, `Msg`) VALUES(?, ?, ?, ?)" + //SQL语句-消息出库 + str_sql_get_message string = "SELECT `Id`, `When`, `From`, `To`, `Msg` FROM `message` WHERE `To`=? ORDER BY `When`" + //SQL语句-消息已送出,清除 + str_sql_delete_message string = "DELETE FROM `message` WHERE `Id`=?" +) diff --git a/stormchat-server/src/stormchat/err.go b/stormchat-server/src/stormchat/err.go new file mode 100644 index 0000000..75e78ad --- /dev/null +++ b/stormchat-server/src/stormchat/err.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "time" +) + +//写日志 +func WriteLog(err string) { + fmt.Fprintln(server.logFile, time.Now().String(), " ", err) +} + +//输出调试信息 +func Debug(msg string) { + if serveMode { + return + } + fmt.Println(msg) +} diff --git a/stormchat-server/src/stormchat/main.go b/stormchat-server/src/stormchat/main.go new file mode 100644 index 0000000..052f0f6 --- /dev/null +++ b/stormchat-server/src/stormchat/main.go @@ -0,0 +1,46 @@ +//主程序 +package main + +import ( + "bufio" + "fmt" + "net" + "os" +) + +var server = NewStormServer() + +func main() { + if server == nil { + fmt.Println("Failed to create service.") + return + } + tcpAddr, _ := net.ResolveTCPAddr("tcp", ":3727") + tcpListener, err := net.ListenTCP("tcp", tcpAddr) + if err != nil { + fmt.Println("Failed to start listening.") + return + } + if serveMode { + server.AcceptLoop(tcpListener) + return + } //服务模式 + //交互模式 + go server.AcceptLoop(tcpListener) + for { + inputReader := bufio.NewReader(os.Stdin) + cmd, _ := inputReader.ReadString('\n') + switch cmd { + case "help\n": + fmt.Println("help") + break + case "quit\n": + case "exit\n": + fmt.Println("bye") + break + default: + fmt.Println("invalid command.") + break + } + } +} diff --git a/stormchat-server/src/stormchat/message.go b/stormchat-server/src/stormchat/message.go new file mode 100644 index 0000000..7103b9e --- /dev/null +++ b/stormchat-server/src/stormchat/message.go @@ -0,0 +1,90 @@ +package main + +import ( + "encoding/base64" + "time" +) + +//消息结构 +type Message struct { + When time.Time //接收时间 + From *UserInfo //发送者 + To *UserInfo //接收者 + Msg []byte //消息体 +} + +//消息存储结构,用于消息数据入库/出库 +type MessageInfo struct { + Id int + When string + From string + To string + Msg string +} + +func NewMessage(msgInfo *MessageInfo) *Message { + m := new(Message) + m.When, _ = time.Parse(time.RFC3339, msgInfo.When) + m.From = QueryUserInfo(msgInfo.From) + m.To = QueryUserInfo(msgInfo.To) + var err error + m.Msg, err = base64.StdEncoding.DecodeString(msgInfo.Msg) + if m.From == nil || m.To == nil || err != nil { + return nil + } + return m +} + +//将消息存储到数据库 +func (message *Message) Save() bool { + _, err := server.db.Exec(str_sql_save_message, message.When.Format(time.RFC3339), + message.From.User, message.To.User, base64.StdEncoding.EncodeToString(message.Msg)) + if err != nil { + WriteLog("SaveMessage Error: " + err.Error()) + return false + } + return true +} + +//查询用户未读消息 +func QuerySavedMessages(user *UserInfo) map[int]Message { + messageMap := make(map[int]Message) + rows, err := server.db.Query(str_sql_get_message, user.User) + if err != nil { + WriteLog("[QuerySavedMessage]Quering Failed: " + err.Error()) + return nil + } + for rows.Next() { + msgInfo := new(MessageInfo) + + scanErr := rows.Scan(&msgInfo.Id, &msgInfo.When, &msgInfo.From, &msgInfo.To, &msgInfo.Msg) + if scanErr != nil { + WriteLog("[QuerySavedMessage]Scan Failed: " + scanErr.Error()) + rows.Close() + return nil + } + m := NewMessage(msgInfo) + if m == nil { + WriteLog("[QuerySavedMessage]Bad Message. " + err.Error()) + DeleteSavedMessage(msgInfo.Id) //删除无效消息 + } else { + messageMap[msgInfo.Id] = *m + } + } + err = rows.Err() + if err != nil { + WriteLog("[QuerySavedMessage]Rows Failed: " + err.Error()) + return nil + } + return messageMap +} + +//删除数据库中的未读消息 +func DeleteSavedMessage(id int) bool { + _, err := server.db.Exec(str_sql_delete_message, id) + if err != nil { + WriteLog("[DeleteSavedMessage]Delete Message Failed: " + err.Error()) + return false + } + return true +} diff --git a/stormchat-server/src/stormchat/session.go b/stormchat-server/src/stormchat/session.go new file mode 100644 index 0000000..af7e531 --- /dev/null +++ b/stormchat-server/src/stormchat/session.go @@ -0,0 +1,451 @@ +package main + +import ( + "encoding/binary" + "encoding/json" + "net" + "strconv" + "strings" + "sync/atomic" + "time" +) + +//当前session的状态 +const ( + session_status_created = iota //已创建,但未确认发送者和接收者身份 + session_status_running // 通道已建立,session正常运行 + session_status_stoped // 标识服务已停止 + session_status_destroyed //消息读写线程已关闭,连接已断开 +) + +type Session struct { + sender *UserInfo //消息发送者 + receiver string //消息接收者 + addr string //客户端地址 + conn *net.TCPConn //TCP连接 + status int32 //session运行状态 + stopChan chan bool //Session终止标识,传递数据即终止。仅由读消息循环用于终止写循环 + writeCh chan []byte //写消息通道 + writeResultCh chan bool //是否写成功 +} + +//初始化 +func NewSession(conn *net.TCPConn) *Session { + var session = new(Session) + session.sender = nil + session.receiver = "" + session.status = session_status_created + session.stopChan = make(chan bool) + session.writeCh = make(chan []byte) + session.writeResultCh = make(chan bool) + session.conn = conn + session.addr = conn.RemoteAddr().String() + return session +} + +//销毁聊天连接 +func (session *Session) Destroy() { + if session.status == session_status_destroyed { + return + } + if session.sender != nil { + delete(server.sessionMap, session.sender.User) + } + session.status = session_status_destroyed + session.conn.Close() + close(session.writeCh) + close(session.writeResultCh) +} + +//消息处理总控制器,根据控制字调用相应处理函数 +//关闭连接时先退出读循环,再关闭写循环,避免造成chan panic +func (session *Session) ReceiveLoop() { + defer func() { + session.stopChan <- true + Debug("[" + session.addr + "]Receive loop ended.") + }() //终止写循环 + Debug("[" + session.addr + "]Receive loop started.") + var err error //错误 + for { + if atomic.LoadInt32(&session.status) == session_status_stoped { + return + } //检查session是否已终止 + //设置超时并等待客户数据 + if !session.waitData(time.Now().Add(timeout_message * time.Second)) { + continue + } + //读取数据 + head := session.readDataWithLength(max_head_length) + data := session.readDataWithLength(max_message_length) + if head == nil || data == nil { + Debug("Failed to read data.") + session.SendPanic("", "Failed to read data.") + continue + } + //解析包头 + headInfo := make(map[string]string) + err = json.Unmarshal(head, &headInfo) + if err != nil { + Debug("Failed to unmarshal head.") + session.SendPanic("", "Failed to unmarshal head.") + continue + } + if session.sender == nil && headInfo[keyname_operation] != operation_login { + session.SendPanic("", "MUST LOGIN") + continue + } //抛弃未登录用户的消息 + switch headInfo[keyname_operation] { + case operation_send_message: + go session.MessageHandler(headInfo, data) + break + case operation_ping: + go session.PingHandler() + break + case operation_login: + session.LoginHandler(headInfo) + break + case operation_logout: + session.LogoutHandler() + break + case operation_get_user_list: + go session.GetUserListHandler(headInfo) + break + case operation_update_userinfo: + go session.UpdateUserInfoHandler(headInfo, data) + break + default: + session.SendPanic(headInfo[keyname_operation], "Unknwon Request") + continue + } + } +} + +//消息写循环(由读循环终止) +func (session *Session) SendLoop() { + Debug("[" + session.addr + "]Send loop started.") + defer session.Destroy() + for { + select { + case data, ok := <-session.writeCh: + if !ok { + atomic.SwapInt32(&session.status, session_status_stoped) + continue + } + writeLen, err := session.conn.Write(data) + if err != nil || (writeLen != len(data)) { + WriteLog(err.Error()) + atomic.SwapInt32(&session.status, session_status_stoped) + session.writeResultCh <- false + continue + } //写失败 + session.writeResultCh <- true + case <-session.stopChan: + Debug("[" + session.addr + "]Send loop ended.") + return + } + } +} + +//响应客户端心跳包 +func (session *Session) PingHandler() { + return +} + +//登录事件处理函数 +func (session *Session) LoginHandler(headInfo map[string]string) { + returnInfo := make(map[string]string) + returnInfo[keyname_operation] = headInfo[keyname_operation] + returnInfo[keyname_token] = headInfo[keyname_token] + returnInfo["Error"] = "" + if session.status != session_status_created { + session.SendData(returnInfo, nil) + return + } //已登录 + user := Login(headInfo["User"], headInfo["Pwd"]) + if user == nil { + Debug("Bad login: illegal user.") + returnInfo["Error"] = "Illegal User." + session.SendData(returnInfo, nil) + return + } + session.sender = user + session.status = session_status_running + session.Offline(server.sessionMap[session.sender.User], "The account is logged by another client.") + server.sessionMap[session.sender.User] = session + userdata, _ := json.Marshal(user) + session.SendData(returnInfo, userdata) + //转发用户未读消息 + go session.TransUnreadedMessages(session.sender) + Debug("Log in successfully.") +} + +//用户登出 +func (session *Session) LogoutHandler() { + //防止其他session传递数据。等待用户断开连接或者再次登录 + delete(server.sessionMap, session.sender.User) + session.sender = nil + session.receiver = "" + if atomic.LoadInt32(&session.status) == session_status_running { + atomic.SwapInt32(&session.status, session_status_created) + } //恢复未登录状态 +} + +//消息处理函数 +func (session *Session) MessageHandler(headInfo map[string]string, msg []byte) { + result := make(map[string]string) + result[keyname_token] = headInfo[keyname_token] + result[keyname_operation] = operation_send_message + result["Error"] = "" + + if headInfo["To"] == "" { + headInfo["To"] = session.receiver + } + var destChat *Session = nil + for key, value := range server.sessionMap { + if key == headInfo["To"] { + destChat = value + break + } + } //判断接收者是否在线 + message := new(Message) + message.When = time.Now() + message.From = session.sender + message.Msg = msg + if destChat != nil { + message.To = destChat.sender + destChat.TransMessage(message) + } else { + message.To = QueryUserInfo(headInfo["To"]) + if message.To != nil { + message.Save() + } else { + result["Error"] = "The message doesn't has a valid receiver." + } //消息接收者不存在 + } + if _, ok := headInfo["NeedResult"]; ok { + session.SendData(result, nil) + } //返回执行结果 +} + +//获取用户列表 +func (session *Session) GetUserListHandler(headInfo map[string]string) bool { + head := make(map[string]string) + head[keyname_token] = headInfo[keyname_token] + head[keyname_operation] = headInfo[keyname_operation] + head["Count"] = "0" + head["Error"] = "" + users := GetUserList() + if users == nil { + head["Error"] = "Server failed to get user list." + session.SendData(head, nil) + return false + } + data, err := json.Marshal(users) + if err != nil { + head["Error"] = "JSON marshal failed: " + err.Error() + WriteLog(head["Error"]) + session.SendData(head, nil) + return false + } + head["Count"] = string(len(users)) + return session.SendData(head, data) +} + +//获取用户头像 +func (session *Session) GetUserPhotoHandler(headInfo map[string]string) { + head := make(map[string]string) + head[keyname_token] = headInfo[keyname_token] + head[keyname_operation] = headInfo[keyname_operation] + head["Error"] = "" + photo := GetUserPhoto(session.sender.User) + session.SendData(head, photo) +} + +//更改用户信息 +func (session *Session) UpdateUserInfoHandler(headInfo map[string]string, data []byte) { + //准备反馈数据 + result := make(map[string]string) + result[keyname_token] = headInfo[keyname_token] + result[keyname_operation] = headInfo[operation_update_userinfo] + result["Error"] = "" + + if item, ok := headInfo["NickName"]; ok { + result["Error"] += session.sender.UpdateNickName(item) + ";" + } //修改昵称 + if item, ok := headInfo["Password"]; ok { + result["Error"] += session.sender.UpdatePassword(item) + ";" + } //修改密码 + if item, ok := headInfo["Motto"]; ok { + result["Error"] += session.sender.UpdateMotto(item) + ";" + } //修改签名 + item, ok := headInfo["Photo"] + i, _ := strconv.Atoi(item) + if ok && i > 0 { + result["Error"] += session.sender.UpdatePhoto(data) + } //修改头像 + session.SendData(result, nil) +} + +/** + * 服务器数据异常,向客户端发送Panic并关闭连接 + * @param curOperation, 当前操作 + * @param errStr, 错误描述 + */ +func (session *Session) SendPanic(curOperation string, errStr string) bool { + if atomic.LoadInt32(&session.status) >= session_status_stoped { + return false + } + Debug("[SendPanic]" + errStr) + defer atomic.SwapInt32(&session.status, session_status_stoped) + data := make(map[string]string) + data[keyname_token] = "" + data[keyname_operation] = operation_panic + data["Job"] = curOperation + data["Error"] = errStr + slice, err := json.Marshal(data) + if err != nil { + return false + } + return session.send(slice, nil) +} + +//发送数据到客户端,包头将被json序列化 +func (session *Session) SendData(headInfo map[string]string, data []byte) bool { + head, err := json.Marshal(headInfo) + if err != nil { + Debug("TransMessage Failed.") + session.SendPanic(headInfo[keyname_operation], "Failed to marshal data.") + return false + } + return session.send(head, data) +} + +//勒令用户下线。调用条件(满足一条): +//相同账户被重复登录 +//用户修改密码 +func (newChat *Session) Offline(oldChat *Session, reason string) bool { + if oldChat == nil { + return true + } + data := make(map[string]string) + data[keyname_token] = "" + data[keyname_operation] = operation_offline + data["Error"] = "Another Login" + data["Addr"] = newChat.addr + defer atomic.SwapInt32(&oldChat.status, session_status_stoped) + return oldChat.SendData(data, nil) +} + +//转发消息 +func (session *Session) TransMessage(msg *Message) bool { + data := make(map[string]string) + data[keyname_token] = "" + data[keyname_operation] = operation_trans_message + data["When"] = msg.When.Format(time.RFC3339) + data["From"] = msg.From.User + return session.SendData(data, []byte(msg.Msg)) +} + +//转发存储在数据库中的未读消息 +func (session *Session) TransUnreadedMessages(user *UserInfo) bool { + messages := QuerySavedMessages(user) + if messages == nil { + return false + } + for id, message := range messages { + if session.TransMessage(&message) { + DeleteSavedMessage(id) + } else { + return false + } + } + Debug("Unreaded message transmitting done.") + return true +} + +//从TCP连接读取数据,取到的前2字节作为数据长度 +func (session *Session) readDataWithLength(max_length uint32) []byte { + var dataLen uint32 //数据长度 + var lenBuffer [4]byte //数据长度缓存区 + var data []byte //数据缓存区 + //获取数据长度 + readedLen, err := session.conn.Read(lenBuffer[0:4]) + if err != nil || readedLen != 4 { + Debug("Failed to read data. Error: " + err.Error()) + return nil + } + dataLen = binary.BigEndian.Uint32(lenBuffer[0:4]) + if dataLen > max_length || dataLen < 0 { + WriteLog("[ReadData]Data length exceeds.") + return nil + } //数据长度超出限制 + data = make([]byte, dataLen) + if dataLen == 0 { + return data + } + readedLen, err = session.conn.Read(data) + if err != nil || readedLen != int(dataLen) { + Debug("[ReadData]Failed to read data." + err.Error()) + return nil + } + return data +} + +//等待客户端数据 +func (session *Session) waitData(deadline time.Time) bool { + var buf = make([]byte, 0, 0) //空缓冲区 + for time.Now().Before(deadline) { + session.conn.SetReadDeadline(time.Now().Add(time.Second)) + _, err := session.conn.Read(buf) + if err == nil { + //消息到达时临时禁止读取超时 + session.conn.SetReadDeadline(time.Now().Add(time.Hour * 24 * 360 * 100)) + return true + } //数据到达 + if atomic.LoadInt32(&session.status) >= session_status_stoped { + return false + } + if strings.HasSuffix(err.Error(), "i/o timeout") { + continue + } //等待数据时正常超时 + atomic.SwapInt32(&session.status, session_status_stoped) + return false + } + return false +} + +/** +* 将数据加工后发送给客户端 +* @param head, 消息头 +* @param data, 消息体 + */ +func (session *Session) send(head []byte, data []byte) bool { + if atomic.LoadInt32(&session.status) >= session_status_stoped { + return false + } + var buf = make([]byte, 4) //长度标识 + var packet = make([]byte, 0, len(head)+len(data)+4+4) //headLen + head + msgLen + data + //写包头 + //取包头长 + binary.BigEndian.PutUint32(buf[0:4], uint32(len(head))) + packet = append(packet, buf...) //写包头长度 + if len(head) > 0 { + packet = append(packet, head...) //写包头 + } + //写数据 + //取数据长 + binary.BigEndian.PutUint32(buf[0:4], uint32(len(data))) + packet = append(packet, buf...) //写数据长度 + if len(data) > 0 { + packet = append(packet, data...) //写数据 + } + + if len(packet) != cap(packet) { + return false + } //数据异常 + if atomic.LoadInt32(&session.status) >= session_status_stoped { + return false + } + session.writeCh <- packet + return <-session.writeResultCh +} diff --git a/stormchat-server/src/stormchat/storm-server.go b/stormchat-server/src/stormchat/storm-server.go new file mode 100644 index 0000000..5eee36b --- /dev/null +++ b/stormchat-server/src/stormchat/storm-server.go @@ -0,0 +1,59 @@ +package main + +import ( + "database/sql" + _ "github.com/go-sql-driver/mysql" + "net" + "os" +) + +type StormServer struct { + listener *net.TCPListener + logFile *os.File //日志文件 + db *sql.DB + sessionMap map[string]*Session //session列表 +} + +//创建服务 +func NewStormServer() *StormServer { + var newServer = new(StormServer) + var err error + //打开日志文件 + if serveMode { + newServer.logFile, err = os.OpenFile(str_log_file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 002) + if err != nil { + Debug("Failed to open log file.") + return nil + } + } else { + newServer.logFile = os.Stderr + } + //连接数据库 + newServer.db, _ = sql.Open("mysql", str_db_conn_str) + err = newServer.db.Ping() + if err != nil { + Debug("Failed to connect to the database.") + return nil + } + + newServer.sessionMap = make(map[string]*Session) + return newServer +} + +//销毁服务 +func (server *StormServer) Destroy() { + if !serveMode { + server.logFile.Close() + } + server.db.Close() +} + +//监听新的TCP连接 +func (server *StormServer) AcceptLoop(tcpListener *net.TCPListener) { + for { + tcpConn, _ := tcpListener.AcceptTCP() + var newChat = NewSession(tcpConn) + go newChat.SendLoop() + go newChat.ReceiveLoop() + } +} diff --git a/stormchat-server/src/stormchat/user.go b/stormchat-server/src/stormchat/user.go new file mode 100644 index 0000000..852344c --- /dev/null +++ b/stormchat-server/src/stormchat/user.go @@ -0,0 +1,133 @@ +package main + +import ( + "encoding/base64" + "unicode/utf8" +) + +//用户信息 +type UserInfo struct { + User string //用户名 + Nickname string //昵称 + Motto string //签名 + UGroup string //用户组。ugroup_*常量值 +} + +//根据用户名查询一个用户。如果用户不存在则返回nil +func QueryUserInfo(userName string) *UserInfo { + user := new(UserInfo) + err := server.db.QueryRow(str_sql_query_user, userName).Scan(&user.User, &user.Nickname, &user.Motto, &user.UGroup) + if err != nil { + return nil + } else { + return user + } +} + +//获取用户头像 +func GetUserPhoto(userName string) []byte { + var photo string + err := server.db.QueryRow(str_sql_get_photo, userName).Scan(&photo) + if err != nil { + return nil + } + photoData, err := base64.StdEncoding.DecodeString(photo) + if err != nil { + return nil + } + return photoData +} + +//登录,成功返回用户信息,失败返回nil +func Login(userName string, pwd string) *UserInfo { + user := new(UserInfo) + err := server.db.QueryRow(str_sql_login, userName, pwd).Scan(&user.User, &user.Nickname, &user.Motto, &user.UGroup) + if err != nil { + if err.Error() == "sql: no rows in result set" { + Debug(err.Error()) + } else { + WriteLog("[Login]Database Error: " + err.Error()) + } + return nil + } else { + return user + } +} + +//获取用户列表 +func GetUserList() []UserInfo { + users := make([]UserInfo, 0, 10) + rows, err := server.db.Query(str_sql_get_users) + defer rows.Close() + if err != nil { + WriteLog("Database Error: " + err.Error()) + return nil + } + for rows.Next() { + user := new(UserInfo) + scanErr := rows.Scan(&user.User, &user.Nickname, &user.Motto, &user.UGroup) + if scanErr != nil { + WriteLog("Database Error - Scan Error: " + scanErr.Error()) + return nil + } + users = append(users, *user) + } + err = rows.Err() + if err != nil { + WriteLog("Database Error: " + err.Error()) + return nil + } + return users +} + +//更改昵称 +func (user *UserInfo) UpdateNickName(newNickName string) (errText string) { + if length := utf8.RuneCountInString(newNickName); length == 0 || length > 12 { + return "Illeagal NickName" + } + _, err := server.db.Exec(str_sql_update_nickname, newNickName, user.User) + if err != nil { + WriteLog("[UpdateNickName]DB Error: " + err.Error()) + return "Database Error" + } + return "" +} + +//更新密码 +func (user *UserInfo) UpdatePassword(newPassword string) (errText string) { + if length := len([]rune(newPassword)); length == 0 || length > 16 { + return "Illeagal Password" + } + _, err := server.db.Exec(str_sql_update_password, newPassword, user.User) + if err != nil { + WriteLog("[UpdatePassword]DB Error: " + err.Error()) + return "Database Error" + } + return "" +} + +//更新签名 +func (user *UserInfo) UpdateMotto(newMotto string) (errText string) { + if length := utf8.RuneCountInString(newMotto); length > 32 { + return "Motto is too long" + } + _, err := server.db.Exec(str_sql_update_motto, newMotto, user.User) + if err != nil { + WriteLog("[UpdateMotto]DB Error: " + err.Error()) + return "Database Error" + } + return "" +} + +//更新头像 +func (user *UserInfo) UpdatePhoto(data []byte) (errText string) { + if uint32(len(data)) > max_photo_size { + return "New photo is too large" + } + _, err := server.db.Exec(str_sql_update_photo, base64.StdEncoding.EncodeToString(data), user.User) + if err != nil { + WriteLog("[UpdatePhoto]DB Error: " + err.Error()) + return "Database Error" + } + return "" +}