Spaces:
Running
Running
| <html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><style>body { | |
| max-width: 980px; | |
| margin: 16px auto; | |
| } | |
| body .markdown-body | |
| { | |
| padding: 45px; | |
| } | |
| @font-face { | |
| font-family: fontawesome-mini; | |
| src: url(data:font/woff;charset=utf-8;base64,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) format('woff'); | |
| } | |
| .markdown-body { | |
| font-family: sans-serif; | |
| -ms-text-size-adjust: 100%; | |
| -webkit-text-size-adjust: 100%; | |
| color: #333333; | |
| overflow: hidden; | |
| font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; | |
| font-size: 16px; | |
| line-height: 1.6; | |
| word-wrap: break-word; | |
| } | |
| .markdown-body a { | |
| background: transparent; | |
| } | |
| .markdown-body a:active, | |
| .markdown-body a:hover { | |
| outline: 0; | |
| } | |
| .markdown-body b, | |
| .markdown-body strong { | |
| font-weight: bold; | |
| } | |
| .markdown-body mark { | |
| background: #ff0; | |
| color: #000; | |
| font-style: italic; | |
| font-weight: bold; | |
| } | |
| .markdown-body sub, | |
| .markdown-body sup { | |
| font-size: 75%; | |
| line-height: 0; | |
| position: relative; | |
| vertical-align: baseline; | |
| } | |
| .markdown-body sup { | |
| top: -0.5em; | |
| } | |
| .markdown-body sub { | |
| bottom: -0.25em; | |
| } | |
| .markdown-body h1 { | |
| font-size: 2em; | |
| margin: 0.67em 0; | |
| } | |
| .markdown-body img { | |
| border: 0; | |
| } | |
| .markdown-body hr { | |
| -moz-box-sizing: content-box; | |
| box-sizing: content-box; | |
| height: 0; | |
| } | |
| .markdown-body pre { | |
| overflow: auto; | |
| } | |
| .markdown-body code, | |
| .markdown-body kbd, | |
| .markdown-body pre, | |
| .markdown-body samp { | |
| font-family: monospace, monospace; | |
| font-size: 1em; | |
| } | |
| .markdown-body input { | |
| color: inherit; | |
| font: inherit; | |
| margin: 0; | |
| } | |
| .markdown-body html input[disabled] { | |
| cursor: default; | |
| } | |
| .markdown-body input { | |
| line-height: normal; | |
| } | |
| .markdown-body input[type="checkbox"] { | |
| box-sizing: border-box; | |
| padding: 0; | |
| } | |
| .markdown-body table { | |
| border-collapse: collapse; | |
| border-spacing: 0; | |
| } | |
| .markdown-body td, | |
| .markdown-body th { | |
| padding: 0; | |
| } | |
| .markdown-body .codehilitetable, | |
| .markdown-body .highlighttable { | |
| border: 0; | |
| border-spacing: 0; | |
| } | |
| .markdown-body .codehilitetable tr, | |
| .markdown-body .highlighttable { | |
| border: 0; | |
| } | |
| .markdown-body .codehilitetable pre, | |
| .markdown-body .codehilitetable div.codehilite, | |
| .markdown-body .highlighttable pre, | |
| .markdown-body .highlighttable div.highlight { | |
| margin: 0; | |
| } | |
| .markdown-body .linenos, | |
| .markdown-body .code, | |
| .markdown-body .codehilitetable td, | |
| .markdown-body .highlighttable td { | |
| border: 0; | |
| padding: 0; | |
| } | |
| .markdown-body td:not(.linenos) .linenodiv { | |
| padding: 0 ; | |
| } | |
| .markdown-body .code { | |
| width: 100%; | |
| } | |
| .markdown-body .linenos div pre, | |
| .markdown-body .linenodiv pre, | |
| .markdown-body .linenodiv { | |
| border: 0; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| -webkit-border-top-left-radius: 3px; | |
| -webkit-border-bottom-left-radius: 3px; | |
| -moz-border-radius-topleft: 3px; | |
| -moz-border-radius-bottomleft: 3px; | |
| border-top-left-radius: 3px; | |
| border-bottom-left-radius: 3px; | |
| } | |
| .markdown-body .code div pre, | |
| .markdown-body .code div { | |
| border: 0; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| -webkit-border-top-right-radius: 3px; | |
| -webkit-border-bottom-right-radius: 3px; | |
| -moz-border-radius-topright: 3px; | |
| -moz-border-radius-bottomright: 3px; | |
| border-top-right-radius: 3px; | |
| border-bottom-right-radius: 3px; | |
| } | |
| .markdown-body * { | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .markdown-body input { | |
| font: 13px Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; | |
| line-height: 1.4; | |
| } | |
| .markdown-body a { | |
| color: #4183c4; | |
| text-decoration: none; | |
| } | |
| .markdown-body a:hover, | |
| .markdown-body a:focus, | |
| .markdown-body a:active { | |
| text-decoration: underline; | |
| } | |
| .markdown-body hr { | |
| height: 0; | |
| margin: 15px 0; | |
| overflow: hidden; | |
| background: transparent; | |
| border: 0; | |
| border-bottom: 1px solid #ddd; | |
| } | |
| .markdown-body hr:before, | |
| .markdown-body hr:after { | |
| display: table; | |
| content: " "; | |
| } | |
| .markdown-body hr:after { | |
| clear: both; | |
| } | |
| .markdown-body h1, | |
| .markdown-body h2, | |
| .markdown-body h3, | |
| .markdown-body h4, | |
| .markdown-body h5, | |
| .markdown-body h6 { | |
| margin-top: 15px; | |
| margin-bottom: 15px; | |
| line-height: 1.1; | |
| } | |
| .markdown-body h1 { | |
| font-size: 30px; | |
| } | |
| .markdown-body h2 { | |
| font-size: 21px; | |
| } | |
| .markdown-body h3 { | |
| font-size: 16px; | |
| } | |
| .markdown-body h4 { | |
| font-size: 14px; | |
| } | |
| .markdown-body h5 { | |
| font-size: 12px; | |
| } | |
| .markdown-body h6 { | |
| font-size: 11px; | |
| } | |
| .markdown-body blockquote { | |
| margin: 0; | |
| } | |
| .markdown-body ul, | |
| .markdown-body ol { | |
| padding: 0; | |
| margin-top: 0; | |
| margin-bottom: 0; | |
| } | |
| .markdown-body ol ol, | |
| .markdown-body ul ol { | |
| list-style-type: lower-roman; | |
| } | |
| .markdown-body ul ul ol, | |
| .markdown-body ul ol ol, | |
| .markdown-body ol ul ol, | |
| .markdown-body ol ol ol { | |
| list-style-type: lower-alpha; | |
| } | |
| .markdown-body dd { | |
| margin-left: 0; | |
| } | |
| .markdown-body code, | |
| .markdown-body pre, | |
| .markdown-body samp { | |
| font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; | |
| font-size: 12px; | |
| } | |
| .markdown-body pre { | |
| margin-top: 0; | |
| margin-bottom: 0; | |
| } | |
| .markdown-body kbd { | |
| background-color: #e7e7e7; | |
| background-image: -moz-linear-gradient(#fefefe, #e7e7e7); | |
| background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); | |
| background-image: linear-gradient(#fefefe, #e7e7e7); | |
| background-repeat: repeat-x; | |
| border-radius: 2px; | |
| border: 1px solid #cfcfcf; | |
| color: #000; | |
| padding: 3px 5px; | |
| line-height: 10px; | |
| font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; | |
| display: inline-block; | |
| } | |
| .markdown-body>*:first-child { | |
| margin-top: 0 ; | |
| } | |
| .markdown-body>*:last-child { | |
| margin-bottom: 0 ; | |
| } | |
| .markdown-body .headerlink { | |
| font: normal 400 16px fontawesome-mini; | |
| vertical-align: middle; | |
| margin-left: -16px; | |
| float: left; | |
| display: inline-block; | |
| text-decoration: none; | |
| opacity: 0; | |
| color: #333; | |
| } | |
| .markdown-body .headerlink:focus { | |
| outline: none; | |
| } | |
| .markdown-body h1 .headerlink { | |
| margin-top: 0.8rem; | |
| } | |
| .markdown-body h2 .headerlink, | |
| .markdown-body h3 .headerlink { | |
| margin-top: 0.6rem; | |
| } | |
| .markdown-body h4 .headerlink { | |
| margin-top: 0.2rem; | |
| } | |
| .markdown-body h5 .headerlink, | |
| .markdown-body h6 .headerlink { | |
| margin-top: 0; | |
| } | |
| .markdown-body .headerlink:hover, | |
| .markdown-body h1:hover .headerlink, | |
| .markdown-body h2:hover .headerlink, | |
| .markdown-body h3:hover .headerlink, | |
| .markdown-body h4:hover .headerlink, | |
| .markdown-body h5:hover .headerlink, | |
| .markdown-body h6:hover .headerlink { | |
| opacity: 1; | |
| text-decoration: none; | |
| } | |
| .markdown-body h1 { | |
| padding-bottom: 0.3em; | |
| font-size: 2.25em; | |
| line-height: 1.2; | |
| border-bottom: 1px solid #eee; | |
| } | |
| .markdown-body h2 { | |
| padding-bottom: 0.3em; | |
| font-size: 1.75em; | |
| line-height: 1.225; | |
| border-bottom: 1px solid #eee; | |
| } | |
| .markdown-body h3 { | |
| font-size: 1.5em; | |
| line-height: 1.43; | |
| } | |
| .markdown-body h4 { | |
| font-size: 1.25em; | |
| } | |
| .markdown-body h5 { | |
| font-size: 1em; | |
| } | |
| .markdown-body h6 { | |
| font-size: 1em; | |
| color: #777; | |
| } | |
| .markdown-body p, | |
| .markdown-body blockquote, | |
| .markdown-body ul, | |
| .markdown-body ol, | |
| .markdown-body dl, | |
| .markdown-body table, | |
| .markdown-body pre, | |
| .markdown-body .admonition { | |
| margin-top: 0; | |
| margin-bottom: 16px; | |
| } | |
| .markdown-body hr { | |
| height: 4px; | |
| padding: 0; | |
| margin: 16px 0; | |
| background-color: #e7e7e7; | |
| border: 0 none; | |
| } | |
| .markdown-body ul, | |
| .markdown-body ol { | |
| padding-left: 2em; | |
| } | |
| .markdown-body ul ul, | |
| .markdown-body ul ol, | |
| .markdown-body ol ol, | |
| .markdown-body ol ul { | |
| margin-top: 0; | |
| margin-bottom: 0; | |
| } | |
| .markdown-body li>p { | |
| margin-top: 16px; | |
| } | |
| .markdown-body dl { | |
| padding: 0; | |
| } | |
| .markdown-body dl dt { | |
| padding: 0; | |
| margin-top: 16px; | |
| font-size: 1em; | |
| font-style: italic; | |
| font-weight: bold; | |
| } | |
| .markdown-body dl dd { | |
| padding: 0 16px; | |
| margin-bottom: 16px; | |
| } | |
| .markdown-body blockquote { | |
| padding: 0 15px; | |
| color: #777; | |
| border-left: 4px solid #ddd; | |
| } | |
| .markdown-body blockquote>:first-child { | |
| margin-top: 0; | |
| } | |
| .markdown-body blockquote>:last-child { | |
| margin-bottom: 0; | |
| } | |
| .markdown-body table { | |
| display: block; | |
| width: 100%; | |
| overflow: auto; | |
| word-break: normal; | |
| word-break: keep-all; | |
| } | |
| .markdown-body table th { | |
| font-weight: bold; | |
| } | |
| .markdown-body table th, | |
| .markdown-body table td { | |
| padding: 6px 13px; | |
| border: 1px solid #ddd; | |
| } | |
| .markdown-body table tr { | |
| background-color: #fff; | |
| border-top: 1px solid #ccc; | |
| } | |
| .markdown-body table tr:nth-child(2n) { | |
| background-color: #f8f8f8; | |
| } | |
| .markdown-body img { | |
| max-width: 100%; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .markdown-body code, | |
| .markdown-body samp { | |
| padding: 0; | |
| padding-top: 0.2em; | |
| padding-bottom: 0.2em; | |
| margin: 0; | |
| font-size: 85%; | |
| background-color: rgba(0,0,0,0.04); | |
| border-radius: 3px; | |
| } | |
| .markdown-body code:before, | |
| .markdown-body code:after { | |
| letter-spacing: -0.2em; | |
| content: "\00a0"; | |
| } | |
| .markdown-body pre>code { | |
| padding: 0; | |
| margin: 0; | |
| font-size: 100%; | |
| word-break: normal; | |
| white-space: pre; | |
| background: transparent; | |
| border: 0; | |
| } | |
| .markdown-body .codehilite, | |
| .markdown-body .highlight { | |
| margin-bottom: 16px; | |
| } | |
| .markdown-body .codehilite pre, | |
| .markdown-body .highlight pre, | |
| .markdown-body pre { | |
| padding: 16px; | |
| overflow: auto; | |
| font-size: 85%; | |
| line-height: 1.45; | |
| background-color: #f7f7f7; | |
| border-radius: 3px; | |
| } | |
| .markdown-body .codehilite pre, | |
| .markdown-body .highlight pre { | |
| margin-bottom: 0; | |
| word-break: normal; | |
| } | |
| .markdown-body pre { | |
| word-wrap: normal; | |
| } | |
| .markdown-body pre code { | |
| display: inline; | |
| max-width: initial; | |
| padding: 0; | |
| margin: 0; | |
| overflow: initial; | |
| line-height: inherit; | |
| word-wrap: normal; | |
| background-color: transparent; | |
| border: 0; | |
| } | |
| .markdown-body pre code:before, | |
| .markdown-body pre code:after { | |
| content: normal; | |
| } | |
| /* Admonition */ | |
| .markdown-body .admonition { | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| position: relative; | |
| border-radius: 3px; | |
| border: 1px solid #e0e0e0; | |
| border-left: 6px solid #333; | |
| padding: 10px 10px 10px 30px; | |
| } | |
| .markdown-body .admonition table { | |
| color: #333; | |
| } | |
| .markdown-body .admonition p { | |
| padding: 0; | |
| } | |
| .markdown-body .admonition-title { | |
| font-weight: bold; | |
| margin: 0; | |
| } | |
| .markdown-body .admonition>.admonition-title { | |
| color: #333; | |
| } | |
| .markdown-body .attention>.admonition-title { | |
| color: #a6d796; | |
| } | |
| .markdown-body .caution>.admonition-title { | |
| color: #d7a796; | |
| } | |
| .markdown-body .hint>.admonition-title { | |
| color: #96c6d7; | |
| } | |
| .markdown-body .danger>.admonition-title { | |
| color: #c25f77; | |
| } | |
| .markdown-body .question>.admonition-title { | |
| color: #96a6d7; | |
| } | |
| .markdown-body .note>.admonition-title { | |
| color: #d7c896; | |
| } | |
| .markdown-body .admonition:before, | |
| .markdown-body .attention:before, | |
| .markdown-body .caution:before, | |
| .markdown-body .hint:before, | |
| .markdown-body .danger:before, | |
| .markdown-body .question:before, | |
| .markdown-body .note:before { | |
| font: normal normal 16px fontawesome-mini; | |
| -moz-osx-font-smoothing: grayscale; | |
| -webkit-user-select: none; | |
| -moz-user-select: none; | |
| -ms-user-select: none; | |
| user-select: none; | |
| line-height: 1.5; | |
| color: #333; | |
| position: absolute; | |
| left: 0; | |
| top: 0; | |
| padding-top: 10px; | |
| padding-left: 10px; | |
| } | |
| .markdown-body .admonition:before { | |
| content: "\f056\00a0"; | |
| color: 333; | |
| } | |
| .markdown-body .attention:before { | |
| content: "\f058\00a0"; | |
| color: #a6d796; | |
| } | |
| .markdown-body .caution:before { | |
| content: "\f06a\00a0"; | |
| color: #d7a796; | |
| } | |
| .markdown-body .hint:before { | |
| content: "\f05a\00a0"; | |
| color: #96c6d7; | |
| } | |
| .markdown-body .danger:before { | |
| content: "\f057\00a0"; | |
| color: #c25f77; | |
| } | |
| .markdown-body .question:before { | |
| content: "\f059\00a0"; | |
| color: #96a6d7; | |
| } | |
| .markdown-body .note:before { | |
| content: "\f040\00a0"; | |
| color: #d7c896; | |
| } | |
| .markdown-body .admonition::after { | |
| content: normal; | |
| } | |
| .markdown-body .attention { | |
| border-left: 6px solid #a6d796; | |
| } | |
| .markdown-body .caution { | |
| border-left: 6px solid #d7a796; | |
| } | |
| .markdown-body .hint { | |
| border-left: 6px solid #96c6d7; | |
| } | |
| .markdown-body .danger { | |
| border-left: 6px solid #c25f77; | |
| } | |
| .markdown-body .question { | |
| border-left: 6px solid #96a6d7; | |
| } | |
| .markdown-body .note { | |
| border-left: 6px solid #d7c896; | |
| } | |
| .markdown-body .admonition>*:first-child { | |
| margin-top: 0 ; | |
| } | |
| .markdown-body .admonition>*:last-child { | |
| margin-bottom: 0 ; | |
| } | |
| /* progress bar*/ | |
| .markdown-body .progress { | |
| display: block; | |
| width: 300px; | |
| margin: 10px 0; | |
| height: 24px; | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| background-color: #ededed; | |
| position: relative; | |
| box-shadow: inset -1px 1px 3px rgba(0, 0, 0, .1); | |
| } | |
| .markdown-body .progress-label { | |
| position: absolute; | |
| text-align: center; | |
| font-weight: bold; | |
| width: 100%; margin: 0; | |
| line-height: 24px; | |
| color: #333; | |
| text-shadow: 1px 1px 0 #fefefe, -1px -1px 0 #fefefe, -1px 1px 0 #fefefe, 1px -1px 0 #fefefe, 0 1px 0 #fefefe, 0 -1px 0 #fefefe, 1px 0 0 #fefefe, -1px 0 0 #fefefe, 1px 1px 2px #000; | |
| -webkit-font-smoothing: antialiased ; | |
| white-space: nowrap; | |
| overflow: hidden; | |
| } | |
| .markdown-body .progress-bar { | |
| height: 24px; | |
| float: left; | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| background-color: #96c6d7; | |
| box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), inset 0 -1px 0 rgba(0, 0, 0, .1); | |
| background-size: 30px 30px; | |
| background-image: -webkit-linear-gradient( | |
| 135deg, rgba(255, 255, 255, .4) 27%, | |
| transparent 27%, | |
| transparent 52%, rgba(255, 255, 255, .4) 52%, | |
| rgba(255, 255, 255, .4) 77%, | |
| transparent 77%, transparent | |
| ); | |
| background-image: -moz-linear-gradient( | |
| 135deg, | |
| rgba(255, 255, 255, .4) 27%, transparent 27%, | |
| transparent 52%, rgba(255, 255, 255, .4) 52%, | |
| rgba(255, 255, 255, .4) 77%, transparent 77%, | |
| transparent | |
| ); | |
| background-image: -ms-linear-gradient( | |
| 135deg, | |
| rgba(255, 255, 255, .4) 27%, transparent 27%, | |
| transparent 52%, rgba(255, 255, 255, .4) 52%, | |
| rgba(255, 255, 255, .4) 77%, transparent 77%, | |
| transparent | |
| ); | |
| background-image: -o-linear-gradient( | |
| 135deg, | |
| rgba(255, 255, 255, .4) 27%, transparent 27%, | |
| transparent 52%, rgba(255, 255, 255, .4) 52%, | |
| rgba(255, 255, 255, .4) 77%, transparent 77%, | |
| transparent | |
| ); | |
| background-image: linear-gradient( | |
| 135deg, | |
| rgba(255, 255, 255, .4) 27%, transparent 27%, | |
| transparent 52%, rgba(255, 255, 255, .4) 52%, | |
| rgba(255, 255, 255, .4) 77%, transparent 77%, | |
| transparent | |
| ); | |
| } | |
| .markdown-body .progress-100plus .progress-bar { | |
| background-color: #a6d796; | |
| } | |
| .markdown-body .progress-80plus .progress-bar { | |
| background-color: #c6d796; | |
| } | |
| .markdown-body .progress-60plus .progress-bar { | |
| background-color: #d7c896; | |
| } | |
| .markdown-body .progress-40plus .progress-bar { | |
| background-color: #d7a796; | |
| } | |
| .markdown-body .progress-20plus .progress-bar { | |
| background-color: #d796a6; | |
| } | |
| .markdown-body .progress-0plus .progress-bar { | |
| background-color: #c25f77; | |
| } | |
| .markdown-body .candystripe-animate .progress-bar{ | |
| -webkit-animation: animate-stripes 3s linear infinite; | |
| -moz-animation: animate-stripes 3s linear infinite; | |
| animation: animate-stripes 3s linear infinite; | |
| } | |
| @-webkit-keyframes animate-stripes { | |
| 0% { | |
| background-position: 0 0; | |
| } | |
| 100% { | |
| background-position: 60px 0; | |
| } | |
| } | |
| @-moz-keyframes animate-stripes { | |
| 0% { | |
| background-position: 0 0; | |
| } | |
| 100% { | |
| background-position: 60px 0; | |
| } | |
| } | |
| @keyframes animate-stripes { | |
| 0% { | |
| background-position: 0 0; | |
| } | |
| 100% { | |
| background-position: 60px 0; | |
| } | |
| } | |
| .markdown-body .gloss .progress-bar { | |
| box-shadow: | |
| inset 0 4px 12px rgba(255, 255, 255, .7), | |
| inset 0 -12px 0 rgba(0, 0, 0, .05); | |
| } | |
| /* MultiMarkdown Critic Blocks */ | |
| .markdown-body .critic_mark { | |
| background: #ff0; | |
| } | |
| .markdown-body .critic_delete { | |
| color: #c82829; | |
| text-decoration: line-through; | |
| } | |
| .markdown-body .critic_insert { | |
| color: #718c00 ; | |
| text-decoration: underline; | |
| } | |
| .markdown-body .critic_comment { | |
| color: #8e908c; | |
| font-style: italic; | |
| } | |
| .markdown-body .headeranchor { | |
| font: normal normal 16px fontawesome-mini; | |
| line-height: 1; | |
| display: inline-block; | |
| text-decoration: none; | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| -webkit-user-select: none; | |
| -moz-user-select: none; | |
| -ms-user-select: none; | |
| user-select: none; | |
| } | |
| .headeranchor:before { | |
| content: '\e157'; | |
| } | |
| .markdown-body .task-list-item { | |
| list-style-type: none; | |
| } | |
| .markdown-body .task-list-item+.task-list-item { | |
| margin-top: 3px; | |
| } | |
| .markdown-body .task-list-item input { | |
| margin: 0 4px 0.25em -20px; | |
| vertical-align: middle; | |
| } | |
| .markdown-body diagram-div, .markdown-body div.uml-sequence-diagram, .markdown-body, div.uml-flowchart { | |
| overflow: auto; | |
| } | |
| /* Media */ | |
| @media only screen and (min-width: 480px) { | |
| .markdown-body { | |
| font-size:14px; | |
| } | |
| } | |
| @media only screen and (min-width: 768px) { | |
| .markdown-body { | |
| font-size:16px; | |
| } | |
| } | |
| @media print { | |
| .markdown-body * { | |
| background: transparent ; | |
| color: black ; | |
| filter:none ; | |
| -ms-filter: none ; | |
| } | |
| .markdown-body { | |
| font-size:12pt; | |
| max-width:100%; | |
| outline:none; | |
| border: 0; | |
| } | |
| .markdown-body a, | |
| .markdown-body a:visited { | |
| text-decoration: underline; | |
| } | |
| .markdown-body .headeranchor-link { | |
| display: none; | |
| } | |
| .markdown-body a[href]:after { | |
| content: " (" attr(href) ")"; | |
| } | |
| .markdown-body abbr[title]:after { | |
| content: " (" attr(title) ")"; | |
| } | |
| .markdown-body .ir a:after, | |
| .markdown-body a[href^="javascript:"]:after, | |
| .markdown-body a[href^="#"]:after { | |
| content: ""; | |
| } | |
| .markdown-body pre { | |
| white-space: pre; | |
| white-space: pre-wrap; | |
| word-wrap: break-word; | |
| } | |
| .markdown-body pre, | |
| .markdown-body blockquote { | |
| border: 1px solid #999; | |
| padding-right: 1em; | |
| page-break-inside: avoid; | |
| } | |
| .markdown-body .progress, | |
| .markdown-body .progress-bar { | |
| -moz-box-shadow: none; | |
| -webkit-box-shadow: none; | |
| box-shadow: none; | |
| } | |
| .markdown-body .progress { | |
| border: 1px solid #ddd; | |
| } | |
| .markdown-body .progress-bar { | |
| height: 22px; | |
| border-right: 1px solid #ddd; | |
| } | |
| .markdown-body tr, | |
| .markdown-body img { | |
| page-break-inside: avoid; | |
| } | |
| .markdown-body img { | |
| max-width: 100% ; | |
| } | |
| .markdown-body p, | |
| .markdown-body h2, | |
| .markdown-body h3 { | |
| orphans: 3; | |
| widows: 3; | |
| } | |
| .markdown-body h2, | |
| .markdown-body h3 { | |
| page-break-after: avoid; | |
| } | |
| } | |
| </style><style>/*GitHub*/ | |
| .highlight {background-color:#fff;color:#333333;} | |
| .highlight .hll {background-color:#ffffcc;} | |
| .highlight .c{color:#999988;font-style:italic} | |
| .highlight .err{color:#a61717;background-color:#e3d2d2} | |
| .highlight .k{font-weight:bold} | |
| .highlight .o{font-weight:bold} | |
| .highlight .cm{color:#999988;font-style:italic} | |
| .highlight .cp{color:#999999;font-weight:bold} | |
| .highlight .c1{color:#999988;font-style:italic} | |
| .highlight .cs{color:#999999;font-weight:bold;font-style:italic} | |
| .highlight .gd{color:#000000;background-color:#ffdddd} | |
| .highlight .ge{font-style:italic} | |
| .highlight .gr{color:#aa0000} | |
| .highlight .gh{color:#999999} | |
| .highlight .gi{color:#000000;background-color:#ddffdd} | |
| .highlight .go{color:#888888} | |
| .highlight .gp{color:#555555} | |
| .highlight .gs{font-weight:bold} | |
| .highlight .gu{color:#800080;font-weight:bold} | |
| .highlight .gt{color:#aa0000} | |
| .highlight .kc{font-weight:bold} | |
| .highlight .kd{font-weight:bold} | |
| .highlight .kn{font-weight:bold} | |
| .highlight .kp{font-weight:bold} | |
| .highlight .kr{font-weight:bold} | |
| .highlight .kt{color:#445588;font-weight:bold} | |
| .highlight .m{color:#009999} | |
| .highlight .s{color:#dd1144} | |
| .highlight .n{color:#333333} | |
| .highlight .na{color:teal} | |
| .highlight .nb{color:#0086b3} | |
| .highlight .nc{color:#445588;font-weight:bold} | |
| .highlight .no{color:teal} | |
| .highlight .ni{color:purple} | |
| .highlight .ne{color:#990000;font-weight:bold} | |
| .highlight .nf{color:#990000;font-weight:bold} | |
| .highlight .nn{color:#555555} | |
| .highlight .nt{color:navy} | |
| .highlight .nv{color:teal} | |
| .highlight .ow{font-weight:bold} | |
| .highlight .w{color:#bbbbbb} | |
| .highlight .mf{color:#009999} | |
| .highlight .mh{color:#009999} | |
| .highlight .mi{color:#009999} | |
| .highlight .mo{color:#009999} | |
| .highlight .sb{color:#dd1144} | |
| .highlight .sc{color:#dd1144} | |
| .highlight .sd{color:#dd1144} | |
| .highlight .s2{color:#dd1144} | |
| .highlight .se{color:#dd1144} | |
| .highlight .sh{color:#dd1144} | |
| .highlight .si{color:#dd1144} | |
| .highlight .sx{color:#dd1144} | |
| .highlight .sr{color:#009926} | |
| .highlight .s1{color:#dd1144} | |
| .highlight .ss{color:#990073} | |
| .highlight .bp{color:#999999} | |
| .highlight .vc{color:teal} | |
| .highlight .vg{color:teal} | |
| .highlight .vi{color:teal} | |
| .highlight .il{color:#009999} | |
| .highlight .gc{color:#999;background-color:#EAF2F5} | |
| </style><title>技术调研</title></head><body><article class="markdown-body"><h1 id="_1">技术调研报告<a class="headerlink" href="#_1" title="Permanent link"></a></h1> | |
| <h2 id="1">1. 目录<a class="headerlink" href="#1" title="Permanent link"></a></h2> | |
| <ul> | |
| <li><a href="#live">直播技术调研</a></li> | |
| <li><a href="#im">IM框架调研</a></li> | |
| <li><a href="#cdn">跨国请求网络解决方案调研</a></li> | |
| </ul> | |
| <h2 id="2">2. 介绍<a class="headerlink" href="#2" title="Permanent link"></a></h2> | |
| <p>此报告旨在对直播技术、IM框架和跨国请求网络解决方案进行调研,以便在项目中做出合适的技术选型。</p> | |
| <p><a id="live"></a></p> | |
| <h2 id="3">3. 直播技术调研<a class="headerlink" href="#3" title="Permanent link"></a></h2> | |
| <h3 id="31">3.1 背景<a class="headerlink" href="#31" title="Permanent link"></a></h3> | |
| <p>项目中需要使用直播相关的功能,需要对市场上直播相关技术进行调研</p> | |
| <h3 id="32">3.2 目标<a class="headerlink" href="#32" title="Permanent link"></a></h3> | |
| <ul> | |
| <li>了解现在市面上流行的直播技术</li> | |
| <li>分析了解直播所使用的技术的优劣</li> | |
| </ul> | |
| <h3 id="33">3.3 调研方法<a class="headerlink" href="#33" title="Permanent link"></a></h3> | |
| <ul> | |
| <li>github了解直播相关开源项目</li> | |
| <li>了解比较大型直播平台的技术架构</li> | |
| </ul> | |
| <h3 id="34">3.4 技术概述<a class="headerlink" href="#34" title="Permanent link"></a></h3> | |
| <h4 id="http-flvhlsrtmpweb-rtcrtsp">直播技术使用实时传输的方式向用户提供视频内容。常用的协议有 HTTP-FLV、HLS、RTMP、Web-RTC、RTSP。<a class="headerlink" href="#http-flvhlsrtmpweb-rtcrtsp" title="Permanent link"></a></h4> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>协议</th> | |
| <th>协议概述</th> | |
| <th>优点</th> | |
| <th>缺点</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td>RTMP</td> | |
| <td>Adobe 公司为Flash/AIR与服务器之间传输音视频数据而开发的私有协议,也是目前最常用的流媒体传输协议。</td> | |
| <td>基于TCP长连接,不需要多次建连,延时低,通常只有1~3s;技术成熟,配套完善。</td> | |
| <td>在PC浏览器中只能通过Flash使用,且无法在移动浏览器使用;鉴于Flash即将退出舞台,所以在网页播放端基本不会以RTMP做拉流。但是是一个很好的推流协议</td> | |
| </tr> | |
| <tr> | |
| <td>HLS</td> | |
| <td>苹果公司提出的基于HTTP的流媒体网络传输协议。其工作原理是切片式传输,把直播流切成无数片,用户在观看视频时,每次客户端可以只下载一部分。</td> | |
| <td>基于HTTP协议,所以接入CDN较为容易,很少被防火墙拦下,且自带多码率自适应;作为苹果提出的协议,在macOS/iOS下有极大优势,Android中也提供了对应的支持;可以说此项协议用在移动设备上是再合适不过了。</td> | |
| <td>延时较大,通常不低于10s 。大量的TS片文件,会造成服务器存储和请求的压力。</td> | |
| </tr> | |
| <tr> | |
| <td>HTTP-FLV</td> | |
| <td>把音视频数据封装成FLV,然后通过HTTP连接传输,与RTMP相比只是传输协议变了。对于网页播放端,本来还是需要Flash才能播放,但「flv.js」的出现又弥补了这个缺陷。</td> | |
| <td>低延时,整体效果与RTMP非常接近;相较于RTMP协议,能有效避免防火墙和代理的影响。</td> | |
| <td>它的传输特性会让流媒体资源缓存在本地客户端,也就是说保密性不怎么样;直到目前仍然不兼容iOS的浏览器。</td> | |
| </tr> | |
| <tr> | |
| <td>WebRTC</td> | |
| <td>基于Google开源技术,在Web端上实现流媒体的协议</td> | |
| <td>RTMP和HLS都是掌握在大企业手中的协议,而WebRTC已被纳入W3C标准;无需安装插件,支持的浏览器越来越多。</td> | |
| <td>厂商对浏览器或系统的定制可能会导致可用性问题,且缺乏服务器端设计和部署方案;传输质量难以保证,优化手段有限;在安卓设备上的兼容性不好;另外,此项协议主要面向Web端,对原生开发支持不足。</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <h4 id="_2">基础直播流程<a class="headerlink" href="#_2" title="Permanent link"></a></h4> | |
| <p><img src="./%E4%B8%80%E4%B8%AA%E7%9B%B4%E6%92%AD%E6%B5%81%E7%A8%8B.png"></p> | |
| <h4 id="_3">参考资料<a class="headerlink" href="#_3" title="Permanent link"></a></h4> | |
| <ul> | |
| <li><a href="https://zhuanlan.zhihu.com/p/485406496">直播协议的选择:RTMP vs HLS vs HTTP-FLV</a></li> | |
| <li><a href="https://www.youtube.com/watch?v=500OEgh2UHs&t=341s&ab_channel=%E5%81%9C%E6%AD%A2%E9%87%8D%E6%9E%84">RTMP、HLS、HTTP-FLV、WebRTC、RTSP的区别?直播协议详解</a></li> | |
| </ul> | |
| <h3 id="35">3.5 主流直播使用协议方案<a class="headerlink" href="#35" title="Permanent link"></a></h3> | |
| <h4 id="351">3.5.1 斗鱼<a class="headerlink" href="#351" title="Permanent link"></a></h4> | |
| <ul> | |
| <li><b>直播技术方案</b>:斗鱼使用 HTTP-FLV 方案来实现视频直播,这是国内几乎所有直播平台都在使用的技术</li> | |
| <li><b>HTTP+P2P FLV 拉流</b>:斗鱼并不完全使用 HTTP 去拉流,而是采用 CDN 和 P2P 两种方式同时去拉流。斗鱼首先会去请求一个完整的 FLV 流,等 P2P 连接好了再去切换成子流。这是因为 P2P 连接比较慢,如果一开始就走 P2P,那么视频起播速度会非常慢。</li> | |
| <li></b>P2P 连接</b>:斗鱼 P2P 是基于 WebRTC 的 DataChannel,可以接收其他用户分享的视频数据,自己也会共享当前下载到的视频数据给其他用户。</li> | |
| <li><b>流量节省</b>:通过 P2P 从其他用户那里拉流可以节省大量流量。例如,一个直播流分为两个子流,一个从 CDN 拉,一个从其他用户那里拉,这样理论上就可以节省 50% 的流量。而斗鱼将一个直播流分成 6 个子流,一个从 CDN 拉,其余 5 个全部从其他用户那里拉,理论上可以节省超过 80% 的直播流量。</li> | |
| <li><b>直播时移</b>:对于赛事直播,斗鱼支持直播时移,这是基于 HLS 的。如果点击一下进度条,斗鱼播放器会黑一下,将 FLV 切换成 HLS。</li> | |
| </ul> | |
| <p><b>总结</b>:斗鱼不仅使用国内常用的 HTTP-FLV 方案,还加入了 P2P 拉流,从而节省 CDN 流量。对于赛事直播,斗鱼还支持直播时移,直播时移是使用 HLS 来实现的,用户在 seek 后会通过 seek 到的时间点去服务器换取对应的时移 HLS 流地址,然后走 HLS 拉流即可。 <a href="https://juejin.cn/post/7121513067728338975">参考资料</a></p> | |
| <h4 id="352-twitch">3.5.2 twitch<a class="headerlink" href="#352-twitch" title="Permanent link"></a></h4> | |
| <ul> | |
| <li>Twitch 的直播流通常是使用 RTMP(Real Time Messaging Protocol)协议进行推流,然后在服务器端将 RTMP 流转换为 HLS(HTTP Live Streaming)流进行分发,用户端则通过 HLS 协议进行拉流。RTMP 协议保持持久连接,并且流数据的传输几乎是实时的,这使得它非常适合用于推送直播流。HLS 协议将直播流切分为一段段小的文件进行传输,客户端下载这些小文件后进行拼接播放,这使得 HLS 协议非常适合用于拉取直播流。<a href="https://toutiao.io/posts/n94sn3/preview">参考资料</a></li> | |
| <li>twitch 将直播技术集成到 <a href="https://aws.amazon.com/cn/ivs/">Amazon Interactive Video Service(IVS)</a>的服务</li> | |
| </ul> | |
| <h3 id="36">3.6 大型直播系统流程架构<a class="headerlink" href="#36" title="Permanent link"></a></h3> | |
| <ul> | |
| <li> | |
| <p><strong>视频直播中心(Live Manage Service)</strong>:负责直播流的逻辑管理和操作控制,包括存储和下发实时转码、加密等媒体处理的配置信息。</p> | |
| </li> | |
| <li> | |
| <p><strong>实时互动直播服务</strong>:由连麦互动和直播两部分组成,主播和连麦者的音视频数据在互动直播高性能服务器合成为一道流后推流到直播流媒体服务器。</p> | |
| </li> | |
| <li> | |
| <p><strong>直播源站服务(Live Source Service)</strong>:自建的直播流媒体服务器节点,结合全局智能调度系统,提供第一公里的最佳链路选择,同时融合支持接入多家CDN厂商。</p> | |
| </li> | |
| <li> | |
| <p><strong>媒体处理服务(Media Processing Service)</strong>:提供实时水印、实时转码、媒体数据加密等强大的流媒体处理能力。</p> | |
| </li> | |
| <li> | |
| <p><strong>融合CDN与全局智能调度(Global Server Load Balancing)</strong>:提供敏捷智能的CDN调度策略和分配算法,结合全链路、端到端的流媒体控制,来达到最终端侧优良的用户体验。</p> | |
| </li> | |
| <li> | |
| <p><strong>客户端SDK</strong>:提供推流、拉流以及上下行的调度能力,便于用户快速接入使用平台一站式的音视频解决方案。</p> | |
| </li> | |
| </ul> | |
| <p><strong>此外,这个架构还包括以下几个关键部分</strong>:</p> | |
| <ul> | |
| <li> | |
| <p><strong>推拉流链路</strong>:这是直播技术架构的核心部分,包括视频直播中心、实时互动直播服务、直播源站服务、媒体处理服务、融合CDN与全局智能调度和客户端SDK。</p> | |
| </li> | |
| <li> | |
| <p><strong>融合CDN与智能调度</strong>:这是一个端到端的服务,通过平台的SDK执行一个类似HTTPDNS的调度,来做到真正根据用户IP做就近的接入。</p> | |
| </li> | |
| <li> | |
| <p><strong>流量精准调度</strong>:大型演唱会直播活动,尤其是正式开播时的进场阶段,突发流量峰值会非常高,这就需要实时精准的智能调度策略。</p> | |
| </li> | |
| <li> | |
| <p><strong>单元化部署</strong>:在大型直播活动中,短时间大量涌入的用户请求,对以全局智能调度服务为主的相关非媒体流链路应用,也提出了更高的并发处理挑战。</p> | |
| </li> | |
| <li> | |
| <p><strong>稳定性保障</strong>:超大型直播方案最核心的诉求就是直播稳定性,包括上行链路稳定和下行链路稳定。</p> | |
| </li> | |
| <li> | |
| <p><strong>安全性保障</strong>:除了直播全链路的稳定之外,直播安全也很重要。包括防盗链鉴权、IP黑白名单、HTTPS等能力,以及地区、运营商等下行调度的动态限制,实现全链路安全保障。</p> | |
| </li> | |
| <li> | |
| <p><strong>监控与报警</strong>:一场大型直播将会有大量的计算节点参与,除了媒体数据处理与分发的各个服务器节点,还有分布在国内外的海量客户端。我们对网络链路、服务节点、设备端的健康与质量感知,都离不开数据监控系统。</p> | |
| </li> | |
| </ul> | |
| <h4 id="_4">参考资料<a class="headerlink" href="#_4" title="Permanent link"></a></h4> | |
| <ul> | |
| <li><a href="https://cloud.tencent.com/developer/article/1979245">直播技术干货分享:千万级直播系统后端架构设计的方方面面</a></li> | |
| <li><a href="https://zhuanlan.zhihu.com/p/427306816">视频直播技术大全、直播架构、技术原理和实现思路方案整理</a></li> | |
| </ul> | |
| <h3 id="36_1">3.6 直播相关开源项目<a class="headerlink" href="#36_1" title="Permanent link"></a></h3> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>项目名</th> | |
| <th>介绍</th> | |
| <th>说明</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><a href="https://github.com/ossrs/srs">srs</a></td> | |
| <td>SRS (Simple Realtime Server) 是一个简单、高效的实时视频服务器</td> | |
| <td>1.支持多种流媒体协议,包括 RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH 和 GB28181。<br/>2.支持多种操作系统和硬件平台。<br/>3.提供了详细的文档,包括如何开始使用、如何从源代码编译等。<br/>4.提供了多种使用示例,包括如何使用 FFmpeg 或 OBS 进行流媒体推送,如何使用 VLC 或网页播放器播放流媒体等。<br/>5.提供了详细的 Wiki,包括如何进行 RTMP 流媒体传输、如何进行 WebRTC 流媒体传输、如何将 RTMP 转换为 HTTP-FLV 流媒体、如何将 RTMP 转换为 HLS 流媒体等。</td> | |
| </tr> | |
| <tr> | |
| <td><a href="https://github.com/gwuhaolin/livego">livego</a></td> | |
| <td>Livego是一个简单且高效的实时广播服务器</td> | |
| <td>1.纯 Golang 编写,性能高,跨平台;<br/>2.支持常用的传输协议、文件格式和编码格式。 支持传输协议:RTMP、AMF、HLS、HTTP-FLV</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <h3 id="37">3.7 直播相关服务<a class="headerlink" href="#37" title="Permanent link"></a></h3> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>服务名</th> | |
| <th>介绍</th> | |
| <th>说明</th> | |
| <th>费用</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><a href="https://aws.amazon.com/cn/ivs/">Amazon Interactive Video Service(IVS</a></td> | |
| <td>亚马逊提供的 twitch 技术的服务</td> | |
| <td><b>托管式直播流</b>:Amazon IVS 提供了一种托管式的直播流解决方案,可以快速为移动和网络应用进行相关设置。<br/><b>直播流托管式聊天</b>:Amazon IVS 提供了直播流托管式聊天功能,可以增强用户的互动体验。<br/><b>多主机直播流</b>:Amazon IVS 支持多主机直播流,可以满足多样化的直播需求。</td> | |
| <td><a href="https://aws.amazon.com/cn/ivs/pricing/">收费策略</a></td> | |
| </tr> | |
| <tr> | |
| <td><a href="https://www.aliyun.com/product/live">ApsaraVideo Live</a></td> | |
| <td>阿里云提供直播服务</td> | |
| <td><b>全链路服务</b>:提供上下行码率自适应、窄带高清转码™、截图、录制、视频审核、时移、数据监控、云导播、超低延时直播、实时日志、视频流管理等功能和服务。<br/><b>全球布局</b>:拥有3200+全球直播节点<br/><b>超低延时</b>毫秒级超低延时,互动更加实时。依托阿里云海内外海量节点资源,实现百万级高并发。</td> | |
| <td><a href="https://help.aliyun.com/zh/live/product-overview/resource-plan-overview?spm=a2c4g.11186623.0.0.c4f331c93jCHZY">收费策略</a></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p><a id="im"></a></p> | |
| <h2 id="4-im">4. IM框架调研<a class="headerlink" href="#4-im" title="Permanent link"></a></h2> | |
| <h3 id="41">4.1 背景<a class="headerlink" href="#41" title="Permanent link"></a></h3> | |
| <p>业务中需要使用到群组、聊天等相关功能。</p> | |
| <h3 id="42">4.2 目标<a class="headerlink" href="#42" title="Permanent link"></a></h3> | |
| <ul> | |
| <li>分析IM框架的性能和稳定性。</li> | |
| <li>了解IM解决方案</li> | |
| </ul> | |
| <h3 id="43">4.3 调研方法<a class="headerlink" href="#43" title="Permanent link"></a></h3> | |
| <ul> | |
| <li>github了解IM相关开源项目</li> | |
| <li>查阅IM相关技术文章</li> | |
| </ul> | |
| <h3 id="44">4.4 技术概述<a class="headerlink" href="#44" title="Permanent link"></a></h3> | |
| <p>即时消息(IM)系统是一种实时通信技术,它允许用户通过网络进行实时交流。IM 技术的主要特点包括实时性、可靠性、一致性和安全性。 </p> | |
| <ul> | |
| <li> | |
| <p><strong>实时性</strong>:IM 系统的核心是实时性,它保证消息的实时传达。如果消息不能即时收到,那么 IM 系统就无法正常工作。</p> | |
| </li> | |
| <li> | |
| <p><strong>可靠性</strong>:IM 系统需要保证消息的不丢失和不重复。如果消息丢失或重复,那么用户的体验将会大大降低。 </p> | |
| </li> | |
| <li> | |
| <p><strong>一致性</strong>:IM 系统需要保证消息的一致性,即保证同一个设备的时间顺序、不同设备的漫游同步。如果不能做到一致性,那么用户在使用 IM 系统时会感到困惑。</p> | |
| </li> | |
| <li> | |
| <p><strong>安全性</strong>:IM 系统需要保证数据传输安全、数据存储安全、消息内容安全。如果不能做到安全性,那么用户的隐私可能会被泄露。 </p> | |
| </li> | |
| </ul> | |
| <p><strong>解决方案</strong>: </p> | |
| <ul> | |
| <li> | |
| <p><strong>实时性</strong>:实时性主要通过优化网络传输和数据处理来实现。使用消息队列和事件驱动模型来提高实时性。消息队列可以缓存消息,避免网络延迟和拥塞,而事件驱动模型可以在数据到达时立即处理数据,提高处理速度。 </p> | |
| </li> | |
| <li> | |
| <p><strong>可靠性</strong>:可靠性主要通过冗余和故障恢复来实现。使用多个服务器来存储和处理数据,如果一个服务器出现故障,其他服务器可以接管它的工作。在这两篇文章中,作者提到了使用分布式系统和数据复制来提高可靠性。分布式系统可以将工作分散到多个服务器上,提高系统的容错能力,而数据复制可以保证数据的完整性和一致性。 </p> | |
| </li> | |
| <li> | |
| <p><strong>一致性</strong>:一致性主要通过数据同步和事务管理来实现。例如,使用数据库的事务功能来保证数据的一致性,或者使用数据同步技术来保证多个服务器上的数据一致。在这两篇文章中,作者提到了使用分布式事务和一致性哈希来保证一致性。分布式事务可以保证在多个服务器上执行的操作的一致性,而一致性哈希可以保证数据在多个服务器上的一致性。 </p> | |
| </li> | |
| <li> | |
| <p><strong>安全性</strong>:安全性主要通过加密和访问控制来实现。例如,使用加密技术来保护数据的安全,或者使用访问控制技术来限制用户的访问权限。在这两篇文章中,作者提到了使用SSL/TLS和身份验证来保证安全性。SSL/TLS可以保证数据在网络传输过程中的安全,而身份验证可以保证只有授权的用户可以访问数据 </p> | |
| </li> | |
| </ul> | |
| <p>IM 的典型架构包括以下几个部分: </p> | |
| <ul> | |
| <li> | |
| <p><strong>客户端</strong>:作为与服务端进行消息收发通信的终端。 </p> | |
| </li> | |
| <li> | |
| <p><strong>接入层</strong>:也叫网关层,为客户端收发消息提供入口。 </p> | |
| </li> | |
| <li> | |
| <p><strong>逻辑层</strong>:负责 IM 系统各功能的核心逻辑实现。 </p> | |
| </li> | |
| <li> | |
| <p><strong>存储层</strong>:负责 IM 系统相关数据的持久化存储,包括消息内容、账号信息、社交关系链等。 </p> | |
| </li> | |
| <li> | |
| <p><strong>第三方服务</strong>:保证 APP 在未打开或后台运行时也能收到消息通知。 </p> | |
| </li> | |
| </ul> | |
| <p><img src="./IM%E7%BB%8F%E5%85%B8%E6%9E%B6%E6%9E%84.png"> </p> | |
| <p>IM 的功能组成主要包括联系人列表、聊天界面、消息发送通道、消息接收通道、消息存储和消息未读数。 </p> | |
| <p><strong>参考文档</strong> </p> | |
| <ul> | |
| <li><a href="https://zhuanlan.zhihu.com/p/158063897">什么是IM系统?</a> </li> | |
| <li><a href="http://www.52im.net/thread-3393-1-1.html">一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分</a> </li> | |
| <li><a href="http://www.52im.net/thread-3445-1-1.html">一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化</a> </li> | |
| </ul> | |
| <h3 id="45">4.5 开源项目<a class="headerlink" href="#45" title="Permanent link"></a></h3> | |
| <h4 id="451-open-im-server">4.5.1 Open-IM-Server<a class="headerlink" href="#451-open-im-server" title="Permanent link"></a></h4> | |
| <p><strong>简介</strong>:Open-IM-Server 是一款即时通讯服务器,使用纯 Golang 开发,采用 JSON over WebSocket 传输协议。在 Open-IM-Server 中,所有东西都是消息,因此您可以轻松扩展自定义消息,而无需修改服务器代码。使用微服务架构,Open-IM-Server 可以使用集群进行部署。通过在服务器上部署 Open-IM-Server,开发人员可以快速地将即时通讯和实时网络功能集成到自己的应用程序中,并确保业务数据的安全性和隐私性。 </p> | |
| <p><strong>GitHub地址</strong>:<a class="magiclink magiclink-github magiclink-repository" href="https://github.com/OpenIMSDK/Open-IM-Server" title="GitHub Repository: OpenIMSDK/Open-IM-Server">OpenIMSDK/Open-IM-Server</a> </p> | |
| <p><strong>官网地址</strong>:<a href="https://www.openim.online/zh">https://www.openim.online/zh</a></p> | |
| <p><strong>优势</strong> </p> | |
| <ul> | |
| <li>完整的实现IM的功能,会话、消息、好友、群组等功能</li> | |
| <li>社区活跃,项目在持续。最近更新了3.0版本</li> | |
| <li>基础聊天功能开源,付费可以支持高级功能(视频会议、朋友圈)但是不提供源码。</li> | |
| </ul> | |
| <p><strong>演示demo</strong>:<a href="https://www.openim.online/zh/demo">https://www.openim.online/zh/demo</a></p> | |
| <p><strong>总结</strong>:实现了基础IM功能,包括服务端和客户端,可以在此基础上快速开发出一套IM应用。</p> | |
| <h4 id="451-im-server">4.5.1 im-server<a class="headerlink" href="#451-im-server" title="Permanent link"></a></h4> | |
| <p><strong>简介</strong>:野火IM是一套通用的即时通讯和实时音视频组件,能够更加容易地赋予客户IM和RTC能力,使客户可以快速的在自有产品上添加聊天和通话功能或者直接使用野火提供的应用。使用野火可以替代云通讯产品或减少自研即时通讯和实时音视频的工作量,降低客户研发成本和难度。 </p> | |
| <p><strong>GitHub地址</strong>:<a class="magiclink magiclink-github magiclink-repository" href="https://github.com/wildfirechat/im-server" title="GitHub Repository: wildfirechat/im-server">wildfirechat/im-server</a></p> | |
| <p><strong>官网地址</strong>:<a href="https://wildfirechat.cn">https://wildfirechat.cn</a> </p> | |
| <p><strong>优势</strong>:与Open-IM-Server类似提供基础功能,一些高级功能需要付费使用</p> | |
| <p><strong>演示demo</strong>:<a href="https://docs.wildfirechat.cn/demo">https://docs.wildfirechat.cn/demo</a></p> | |
| <p><strong>总结</strong>:实现了基础IM功能,包括服务端和客户端,可以在此基础上快速开发出一套IM应用。</p> | |
| <!----> | |
| <h3 id="46">4.6 相关服务<a class="headerlink" href="#46" title="Permanent link"></a></h3> | |
| <h4 id="461-im">4.6.1 腾讯云IM<a class="headerlink" href="#461-im" title="Permanent link"></a></h4> | |
| <p><strong>简介</strong>:即时通信 IM(Instant Messaging)基于腾讯二十余年的 IM 技术积累,支持Android、iOS、Mac、Windows、Web、H5、小程序平台且跨终端互通,低代码 UI 组件助您30分钟集成单聊、群聊、关系链、消息漫游、群组管理、资料管理、直播弹幕和内容审核等能力。适用于直播互动、电商带货、客服咨询、社交沟通、在线课程、企业办公、互动游戏、医疗健康等场景。 </p> | |
| <p><strong>地址</strong>:<a href="https://cloud.tencent.com/product/im">https://cloud.tencent.com/product/im</a></p> | |
| <h4 id="462">4.6.2 网易云信<a class="headerlink" href="#462" title="Permanent link"></a></h4> | |
| <p><strong>简介</strong>: 稳定可靠,海量并发,弱网消息必达, 加密传输,多重备份,选择性托管账号, 4步接入,支持公有云与私有云部署,全球多点,保障海外消息实时到达</p> | |
| <p><strong>地址</strong>:<a href="https://netease.im/">https://netease.im/</a></p> | |
| <p><a id="cdn"></a></p> | |
| <h2 id="5">5. 跨国请求网络解决方案调研<a class="headerlink" href="#5" title="Permanent link"></a></h2> | |
| <h3 id="51">5.1 背景<a class="headerlink" href="#51" title="Permanent link"></a></h3> | |
| <p>项目需要在国外使用,涉及到跨国网络通信可能会有 网络延迟、数据丢包、网络稳定性、数据安全和隐私等问题</p> | |
| <h3 id="52">5.2 目标<a class="headerlink" href="#52" title="Permanent link"></a></h3> | |
| <ul> | |
| <li>了解跨国通讯这些问题的技术解决方案</li> | |
| <li>了解云服务商提供的解决方案</li> | |
| </ul> | |
| <h3 id="53">5.3 调研方法<a class="headerlink" href="#53" title="Permanent link"></a></h3> | |
| <ul> | |
| <li>Google 检索跨国通讯相关问题</li> | |
| <li>查找不同与服务商的不同结局方案</li> | |
| </ul> | |
| <h3 id="54">5.4 技术概述<a class="headerlink" href="#54" title="Permanent link"></a></h3> | |
| <h4 id="541">5.4.1 跨国通讯会产生的问题<a class="headerlink" href="#541" title="Permanent link"></a></h4> | |
| <ul> | |
| <li> | |
| <p><strong>网络延迟</strong>:由于物理距离和网络拥堵,数据在网络中传输需要一定的时间,这就导致了网络延迟。对于需要实时交互的应用(如在线游戏、视频会议等),网络延迟可能会严重影响用户体验。</p> | |
| </li> | |
| <li> | |
| <p><strong>数据丢包</strong>:在复杂的网络环境中,数据包可能会在传输过程中丢失,导致数据不完整或需要重传,这会影响网络性能和应用的响应速度。</p> | |
| </li> | |
| <li> | |
| <p><strong>网络稳定性</strong>:网络的稳定性可能会受到各种因素的影响,包括网络设备的故障、网络拥堵、恶劣天气等。网络不稳定可能会导致服务中断或性能下降。</p> | |
| </li> | |
| <li> | |
| <p><strong>数据安全和隐私</strong>:跨国网络请求可能需要通过公共互联网或者不受信任的网络进行传输,这可能会带来数据安全和隐私的风险。</p> | |
| </li> | |
| <li> | |
| <p><strong>法规和政策</strong>:不同的国家和地区可能有不同的网络法规和政策,包括数据保护、数据主权、网络审查等。这可能会对跨国网络请求带来额外的复杂性和挑战。</p> | |
| </li> | |
| <li> | |
| <p><strong>网络兼容性</strong>:不同地区可能使用不同的网络技术和标准,这可能会导致兼容性问题,影响服务的可用性和性能。</p> | |
| </li> | |
| <li> | |
| <p><strong>时区和语言</strong>:跨国服务需要考虑到时区和语言的差异,这可能会对服务的设计和运营带来额外的挑战。</p> | |
| </li> | |
| </ul> | |
| <h4 id="542">5.4.2 解决方案<a class="headerlink" href="#542" title="Permanent link"></a></h4> | |
| <ul> | |
| <li> | |
| <p><strong>网络延迟</strong>:使用内容分发网络(CDN)将数据缓存到离用户最近的节点,或者使用全球负载均衡器将请求路由到最佳的服务器,都可以减少网络延迟。此外,优化的网络协议(如QUIC、HTTP/3等)也可以减少网络延迟。</p> | |
| </li> | |
| <li> | |
| <p><strong>数据丢包</strong>:使用更可靠的网络协议(如TCP)可以减少数据丢包的问题。此外,一些网络设备和软件也提供了错误检测和重传机制,以确保数据的完整性。</p> | |
| </li> | |
| <li> | |
| <p><strong>网络稳定性</strong>:使用冗余的网络连接和设备,以及自动故障转移机制,可以提高网络的稳定性。此外,一些云服务提供商也提供了网络性能保证(如SLA)。</p> | |
| </li> | |
| <li> | |
| <p><strong>数据安全和隐私</strong>:使用加密技术(如SSL/TLS)可以保护数据在传输过程中的安全。此外,一些云服务提供商也提供了数据隔离和访问控制的功能,以保护数据的隐私。</p> | |
| </li> | |
| <li> | |
| <p><strong>法规和政策</strong>:在设计和实施跨国网络服务时,需要充分考虑各国和地区的法规和政策,并可能需要寻求专业的法律咨询。</p> | |
| </li> | |
| <li> | |
| <p><strong>网络兼容性</strong>:使用标准化的网络技术和协议,以及兼容性测试,可以减少网络兼容性的问题。</p> | |
| </li> | |
| <li> | |
| <p><strong>时区和语言</strong>:在设计和实施服务时,需要考虑到时区和语言的差异,例如,提供多语言的用户界面,以及考虑到时区在处理时间和日期的时候。</p> | |
| </li> | |
| </ul> | |
| <h3 id="55">5.5 云服务供应商解决方案<a class="headerlink" href="#55" title="Permanent link"></a></h3> | |
| <h4 id="551">5.5.1 亚马逊<a class="headerlink" href="#551" title="Permanent link"></a></h4> | |
| <ul> | |
| <li><strong>概述</strong>:AWS全球加速器是一种联网服务,可以帮助提高公共应用程序的可用性、性能和安全性。它提供两个全球静态公共IP,作为应用程序端点的固定入口点,如应用程序负载均衡器、网络负载均衡器、Amazon Elastic Compute Cloud(EC2)实例和弹性IP。用户可以通过静态IP地址访问应用程序端点,享受独立于DNS的确定性路由。AWS全球加速器还提供了流量管理器、API加速、全球静态IP和低延迟游戏和媒体工作负载等使用案例。</li> | |
| <li><strong>地址</strong>:<a href="https://aws.amazon.com/cn/global-accelerator/">https://aws.amazon.com/cn/global-accelerator/</a> </li> | |
| </ul> | |
| <h4 id="552">5.5.2 阿里云<a class="headerlink" href="#552" title="Permanent link"></a></h4> | |
| <ul> | |
| <li><strong>概述</strong>:阿里云全球加速是一款覆盖全球的网络加速服务,依托阿里云优质BGP带宽和全球传输网络,实现全球网络就近接入,可以减少延迟、抖动、丢包等网络问题对服务质量的影响,为全球用户提供高可用和高性能的网络加速服务。它支持多种接入方式,为全球多地域用户提供一张全球加速网络,端到端的加速用户访问后端服务,提升服务访问体验。</li> | |
| <li><strong>地址</strong>:<a href="https://help.aliyun.com/document_detail/153189.html">https://help.aliyun.com/document_detail/153189.html</a> </li> | |
| </ul> | |
| <h4 id="552_1">5.5.2 腾讯云<a class="headerlink" href="#552_1" title="Permanent link"></a></h4> | |
| <ul> | |
| <li><strong>概述</strong>:腾讯云全球应用加速依赖全球节点之间的高速通道、转发集群及智能路由技术,实现各地用户的就近接入,通过高速通道直达源站区域,帮助业务解决全球用户访问卡顿或者延迟过高的问题。它提供图形化配置界面,只需几分钟,用户就可以创建并使用高速通道访问业务源站,并通过控制台查看通道的运行情况。 </li> | |
| <li><strong>地址</strong>:<a href="https://cloud.tencent.com/document/product/608/13759">https://cloud.tencent.com/document/product/608/13759</a> </li> | |
| </ul> | |
| <h4 id="552_2">5.5.2 华为云<a class="headerlink" href="#552_2" title="Permanent link"></a></h4> | |
| <ul> | |
| <li><strong>概述</strong>:华为云全球加速服务为全球化业务用户提供应用加速服务,通过提供统一的公网IP和高可靠、低延时、易管理、安全合规的网络服务,使终端用户在全球能快速访问云上应用,获得优质体验。全球加速实例会为相应加速区域分配一个Anycast IP,客户端流量根据监听器配置通过Anycast IP就近从接入点接入华为云骨干网络,将客户端的访问请求分发至最佳终端节点。 </li> | |
| <li><strong>地址</strong>:<a href="https://support.huaweicloud.com/productdesc-ga/ga_01_0001.html">https://support.huaweicloud.com/productdesc-ga/ga_01_0001.html</a> </li> | |
| </ul></article></body></html><script async> | |
| document.write( | |
| '<script src="http://' + | |
| (location.host || 'localhost').split(':')[0] + | |
| ':35729/livereload.js?snipver=1" async></' + | |
| 'script>') | |
| </script> | |