<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Golang on 首页 | Widegram</title>
    <link>https://widegram.com/tags/golang/</link>
    <description>Recent content in Golang on 首页 | Widegram</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 11 Nov 2021 19:40:00 +0000</lastBuildDate><atom:link href="https://widegram.com/tags/golang/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Golang TCP 即时通讯实例</title>
      <link>https://widegram.com/2021/11/golang-chat/</link>
      <pubDate>Thu, 11 Nov 2021 19:40:00 +0000</pubDate>
      
      <guid>https://widegram.com/2021/11/golang-chat/</guid>
      <description>main.go
package main func main(){ server := NewServer(&amp;#34;127.0.0.1&amp;#34;, 8888) server.Start() } server.go
package main import( &amp;#34;fmt&amp;#34; &amp;#34;net&amp;#34; &amp;#34;sync&amp;#34; &amp;#34;io&amp;#34; &amp;#34;time&amp;#34; ) type Server struct { Ip string Port int //在线用户列表 OnlineMap map[string]*User mapLock sync.RWMutex //消息广播channel Message chan string } func NewServer(ip string,port int) *Server { server := &amp;amp;Server { Ip:	ip, Port:	port, OnlineMap: make(map[string]*User), Message: make(chan string), } return server } //监听Message广播消息channel的goroutine，一旦有消息就发送给全部在线的User func (this *Server) ListenMessager() { for { msg := &amp;lt;-this.</description>
      <content:encoded><![CDATA[<p>main.go</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>(){
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">server</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">NewServer</span>(<span style="color:#e6db74">&#34;127.0.0.1&#34;</span>, <span style="color:#ae81ff">8888</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">Start</span>()
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>server.go</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span>(
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;net&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;sync&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;io&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;time&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Server</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">Ip</span> 		<span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">Port</span> 	<span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//在线用户列表
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OnlineMap</span> <span style="color:#66d9ef">map</span>[<span style="color:#66d9ef">string</span>]<span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">mapLock</span> <span style="color:#a6e22e">sync</span>.<span style="color:#a6e22e">RWMutex</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//消息广播channel
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">Message</span> <span style="color:#66d9ef">chan</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">NewServer</span>(<span style="color:#a6e22e">ip</span> <span style="color:#66d9ef">string</span>,<span style="color:#a6e22e">port</span> <span style="color:#66d9ef">int</span>) <span style="color:#f92672">*</span><span style="color:#a6e22e">Server</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">server</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Server</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Ip</span>:		<span style="color:#a6e22e">ip</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Port</span>:	<span style="color:#a6e22e">port</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">OnlineMap</span>: make(<span style="color:#66d9ef">map</span>[<span style="color:#66d9ef">string</span>]<span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>),
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Message</span>: make(<span style="color:#66d9ef">chan</span> <span style="color:#66d9ef">string</span>),
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">server</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">//监听Message广播消息channel的goroutine，一旦有消息就发送给全部在线的User
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Server</span>) <span style="color:#a6e22e">ListenMessager</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">msg</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&lt;-</span><span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Message</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//发送给全部到在线User
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Lock</span>()
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">cli</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">OnlineMap</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">cli</span>.<span style="color:#a6e22e">C</span> <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">msg</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Unlock</span>()
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Server</span>) <span style="color:#a6e22e">Broadcast</span>(<span style="color:#a6e22e">user</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>, <span style="color:#a6e22e">msg</span> <span style="color:#66d9ef">string</span>) {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">sendMsg</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">&#34;[&#34;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">Addr</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;]&#34;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">Name</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;:&#34;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">msg</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Message</span> <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">sendMsg</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Server</span>) <span style="color:#a6e22e">Handler</span>(<span style="color:#a6e22e">conn</span> <span style="color:#a6e22e">net</span>.<span style="color:#a6e22e">Conn</span>) {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//fmt.Println(&#34;linked ok&#34;)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#75715e">//用户上线了,将用户加入到onlineMap
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">user</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">NewUser</span>(<span style="color:#a6e22e">conn</span>,<span style="color:#a6e22e">this</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">Online</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//用户是否活跃
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">isLive</span> <span style="color:#f92672">:=</span> make(<span style="color:#66d9ef">chan</span> <span style="color:#66d9ef">bool</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">go</span> <span style="color:#66d9ef">func</span>() {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">buf</span> <span style="color:#f92672">:=</span> make([]<span style="color:#66d9ef">byte</span>, <span style="color:#ae81ff">4096</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">n</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">conn</span>.<span style="color:#a6e22e">Read</span>(<span style="color:#a6e22e">buf</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">n</span><span style="color:#f92672">==</span><span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">Offline</span>()
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#a6e22e">io</span>.<span style="color:#a6e22e">EOF</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;conn read err&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>			<span style="color:#75715e">//提取用户消息（去掉&#39;\n&#39;）
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>			<span style="color:#a6e22e">msg</span> <span style="color:#f92672">:=</span> string(<span style="color:#a6e22e">buf</span>[:<span style="color:#a6e22e">n</span><span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>])
</span></span><span style="display:flex;"><span>			
</span></span><span style="display:flex;"><span>			<span style="color:#75715e">//消息处理
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>			<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">DoMessage</span>(<span style="color:#a6e22e">msg</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>			<span style="color:#75715e">//用户依然活跃
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>			<span style="color:#a6e22e">isLive</span> <span style="color:#f92672">&lt;-</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>			
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}()
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//当前handler阻塞
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">select</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">case</span> <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">isLive</span>:
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">case</span> <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">time</span>.<span style="color:#a6e22e">After</span>(<span style="color:#a6e22e">time</span>.<span style="color:#a6e22e">Second</span> <span style="color:#f92672">*</span> <span style="color:#ae81ff">300</span>):<span style="color:#75715e">//更新计时器
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>			<span style="color:#75715e">//已经超时
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>			<span style="color:#75715e">//强制关闭当前的User
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>			<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">SendMessage</span>(<span style="color:#e6db74">&#34;你被踢了\n&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>			close(<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">C</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">conn</span>.<span style="color:#a6e22e">Close</span>()
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#75715e">//runtime.Goexit()
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Server</span>) <span style="color:#a6e22e">Start</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//socket listen
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">listener</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">net</span>.<span style="color:#a6e22e">Listen</span>(<span style="color:#e6db74">&#34;tcp&#34;</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;%s:%d&#34;</span>, <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Ip</span>, <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Port</span>))
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;net.listen err:&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//close listen socket
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">defer</span> <span style="color:#a6e22e">listener</span>.<span style="color:#a6e22e">Close</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//启动监听
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">go</span> <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">ListenMessager</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//accept
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">conn</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">listener</span>.<span style="color:#a6e22e">Accept</span>()
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;listener.accept err:&#34;</span>,<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">continue</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//do handler
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#66d9ef">go</span> <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Handler</span>(<span style="color:#a6e22e">conn</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>user.go</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;net&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;strings&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">User</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">Name</span>	<span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">Addr</span>	<span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">C</span>		<span style="color:#66d9ef">chan</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">conn</span> 	<span style="color:#a6e22e">net</span>.<span style="color:#a6e22e">Conn</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">server</span>  <span style="color:#f92672">*</span><span style="color:#a6e22e">Server</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">NewUser</span>(<span style="color:#a6e22e">conn</span> <span style="color:#a6e22e">net</span>.<span style="color:#a6e22e">Conn</span>, <span style="color:#a6e22e">server</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Server</span>) <span style="color:#f92672">*</span><span style="color:#a6e22e">User</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">userAddr</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">conn</span>.<span style="color:#a6e22e">RemoteAddr</span>().<span style="color:#a6e22e">String</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">User</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Name</span>: <span style="color:#a6e22e">userAddr</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Addr</span>: <span style="color:#a6e22e">userAddr</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">C</span>:	  make(<span style="color:#66d9ef">chan</span> <span style="color:#66d9ef">string</span>),
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">conn</span>: <span style="color:#a6e22e">conn</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">server</span>:<span style="color:#a6e22e">server</span>,
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">go</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">ListenMessage</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">user</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//用户上线
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>) <span style="color:#a6e22e">Online</span>(){
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Lock</span>()
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">OnlineMap</span>[<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Name</span>] = <span style="color:#a6e22e">this</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Unlock</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">Broadcast</span>(<span style="color:#a6e22e">this</span>, <span style="color:#e6db74">&#34;上线了&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//用户下线
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>) <span style="color:#a6e22e">Offline</span>(){
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Lock</span>()
</span></span><span style="display:flex;"><span>	delete(<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">OnlineMap</span>, <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Name</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Unlock</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">Broadcast</span>(<span style="color:#a6e22e">this</span>, <span style="color:#e6db74">&#34;下线了&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//发送消息给user
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>) <span style="color:#a6e22e">SendMessage</span>(<span style="color:#a6e22e">msg</span> <span style="color:#66d9ef">string</span>){
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">conn</span>.<span style="color:#a6e22e">Write</span>([]byte(<span style="color:#a6e22e">msg</span>))
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//处理消息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>) <span style="color:#a6e22e">DoMessage</span>(<span style="color:#a6e22e">msg</span> <span style="color:#66d9ef">string</span>){
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">msg</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;who&#34;</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//查询所有用户信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Lock</span>()
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">user</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">OnlineMap</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">onlineMsg</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">&#34;[&#34;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">Addr</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;]&#34;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">Name</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;: 在线...\n&#34;</span>
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">SendMessage</span>(<span style="color:#a6e22e">onlineMsg</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Unlock</span>()
</span></span><span style="display:flex;"><span>	} <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> len(<span style="color:#a6e22e">msg</span>) &gt; <span style="color:#ae81ff">7</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">msg</span>[:<span style="color:#ae81ff">7</span>] <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;rename|&#34;</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//改名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">newName</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Split</span>(<span style="color:#a6e22e">msg</span>, <span style="color:#e6db74">&#34;|&#34;</span>)[<span style="color:#ae81ff">1</span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//名字是否重复
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">ok</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">OnlineMap</span>[<span style="color:#a6e22e">newName</span>]
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">ok</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">SendMessage</span>(<span style="color:#e6db74">&#34;用户名已被使用！\n&#34;</span>)
</span></span><span style="display:flex;"><span>		} <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Lock</span>()
</span></span><span style="display:flex;"><span>			delete(<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">OnlineMap</span>, <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Name</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">OnlineMap</span>[<span style="color:#a6e22e">newName</span>] = <span style="color:#a6e22e">this</span>
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">mapLock</span>.<span style="color:#a6e22e">Unlock</span>()
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	} <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> len(<span style="color:#a6e22e">msg</span>) &gt; <span style="color:#ae81ff">4</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">msg</span>[:<span style="color:#ae81ff">3</span>] <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;to|&#34;</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//私聊功能
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#75715e">//1 获取对方用户名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">remoteName</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Split</span>(<span style="color:#a6e22e">msg</span>, <span style="color:#e6db74">&#34;|&#34;</span>)[<span style="color:#ae81ff">1</span>]
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">remoteName</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;&#34;</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">SendMessage</span>(<span style="color:#e6db74">&#34;消息格式不正确！\n&#34;</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">remoteUser</span>, <span style="color:#a6e22e">ok</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">OnlineMap</span>[<span style="color:#a6e22e">remoteName</span>]
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> !<span style="color:#a6e22e">ok</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">SendMessage</span>(<span style="color:#e6db74">&#34;用户名不存在\n&#34;</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">content</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Split</span>(<span style="color:#a6e22e">msg</span>, <span style="color:#e6db74">&#34;|&#34;</span>)[<span style="color:#ae81ff">2</span>]
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">content</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;&#34;</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">SendMessage</span>(<span style="color:#e6db74">&#34;空消息无法发送！\n&#34;</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">remoteUser</span>.<span style="color:#a6e22e">SendMessage</span>(<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">Name</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;向您发送&#34;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">content</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;\n&#34;</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//2 找到对方user对象
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#75715e">//3 发送内容
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	} <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">server</span>.<span style="color:#a6e22e">Broadcast</span>(<span style="color:#a6e22e">this</span>, <span style="color:#a6e22e">msg</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//监听当前user的channel，有消息就写入对端客户端
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">this</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">User</span>) <span style="color:#a6e22e">ListenMessage</span>(){
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">msg</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&lt;-</span><span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">C</span>
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">this</span>.<span style="color:#a6e22e">conn</span>.<span style="color:#a6e22e">Write</span>([]byte(<span style="color:#a6e22e">msg</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;\n&#34;</span>))
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
  </channel>
</rss>
