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 0000000..0666297 Binary files /dev/null and b/stormchat-client/res/conctrl_x64.dll differ diff --git a/stormchat-client/res/icon.ico b/stormchat-client/res/icon.ico new file mode 100644 index 0000000..b25e7b8 Binary files /dev/null and b/stormchat-client/res/icon.ico differ 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 0000000..019e492 Binary files /dev/null and b/stormchat-client/src/stormchat-client.syso differ 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 "" +}