




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第300行代碼實現(xiàn)go語言即時通訊聊天室學了2年Java,因為工作原因需要轉(zhuǎn)Golang,3天時間學習了下go的基本語法,做這樣一個聊天室小項目來鞏固串聯(lián)一下語法。
實現(xiàn)的功能:公聊,私聊,修改用戶名
只用到了四個類:
main.go:用來啟動服務器server.go:服務器相關(guān)代碼client.go:客戶端相關(guān)代碼,用戶可以直接操作的可視化界面user.go:用戶類,用來封裝用戶的業(yè)務邏輯
架構(gòu)圖
server.go
packagemain
import(
"fmt"
"io"
"net"
"sync"
"time"
typeServerstruct{
Ipstring
Portint
//在線用戶列表
OnlineMapmap[string]*User
mapLocksync.RWMutex
//消息廣播的Channel
Messagechanstring
funcNewServer(ipstring,portint)*Server{
server:=Server{
Ip:ip,
Port:port,
OnlineMap:make(map[string]*User),
Message:make(chanstring),
returnserver
func(s*Server)Handler(connnet.Conn){
//業(yè)務邏輯
//fmt.Println("鏈接建立成功")
user:=NewUser(conn,s)
user.Online()
//監(jiān)聽用戶是否活躍
isLive:=make(chanbool)
gofunc(){
buf:=make([]byte,4096)
for{
n,error:=conn.Read(buf)
ifn==0{
user.Offline()
return
iferror!=nilerror!=io.EOF{
fmt.Println("readerror")
msg:=string(buf[:n-1])
user.DoMessage(msg)
//表示用戶活躍
isLive-true
for{
select{
case-isLive:
//當前用戶活躍,不做任何時,激活select,重置定時器
case-time.After(time.Second*300):
//超時,將user強制關(guān)閉
user.SendMsg("你被踢了")
close(user.C)
conn.Close()
return
func(s*Server)ListenMessager(){
for{
msg:=-s.Message
s.mapLock.Lock()
for_,user:=ranges.OnlineMap{
user.C-msg
s.mapLock.Unlock()
func(s*Server)BroadCast(user*User,msgstring){
sendMsg:="["+user.Addr+"]"+user.Name+":"+msg
s.Message-sendMsg
func(s*Server)Start(){
listener,error:=net.Listen("tcp",fmt.Sprintf("%s:%d",s.Ip,s.Port))
iferror!=nil{
fmt.Println("listenererror...")
return
deferlistener.Close()
gos.ListenMessager()
for{
conn,error:=listener.Accept()
iferror!=nil{
fmt.Println("accepterror...")
continue
gos.Handler(conn)
client.go
packagemain
import(
"flag"
"fmt"
"io"
"net"
"os"
typeClientstruct{
ServerIpstring
ServerPortint
Namestring
connnet.Conn
flagint
funcNewClient(serverIpstring,serverPortint)*Client{
client:=Client{
ServerIp:serverIp,
ServerPort:serverPort,
flag:9999,
conn,error:=net.Dial("tcp",fmt.Sprintf("%s:%d",serverIp,serverPort))
iferror!=nil{
fmt.Println("netdialerror...")
returnnil
client.conn=conn
returnclient
func(c*Client)menu()bool{
varflagint
fmt.Println("1.公聊模式")
fmt.Println("2.私聊模式")
fmt.Println("3.修改用戶名")
fmt.Println("0.退出")
fmt.Scanln(flag)
ifflag=0flag=3{
c.flag=flag
returntrue
}else{
fmt.Println("請輸入合法數(shù)字")
returnfalse
//修改用戶名
func(c*Client)UpdateName()bool{
fmt.Println("請輸入用戶名")
fmt.Scanln(c.Name)
sendMsg:="rename|"+c.Name+"\n"
_,error:=c.conn.Write([]byte(sendMsg))
iferror!=nil{
fmt.Println("conn.writeerror...")
returnfalse
returntrue
func(c*Client)PublicChat(){
varchatMsgstring
fmt.Println("請輸入聊天內(nèi)容,輸入exit退出")
fmt.Scanln(chatMsg)
forchatMsg!="exit"{
iflen(chatMsg)!=0{
msg:=chatMsg+"\n"
_,error:=c.conn.Write([]byte(msg))
iferror!=nil{
fmt.Println("conn.Writeerror....")
break
chatMsg=""
fmt.Println("請輸入聊天內(nèi)容,輸入exit退出")
fmt.Scanln(chatMsg)
func(c*Client)PrivateChat(){
varremoteUserstring
varchatMsgstring
c.SelectUsers()
fmt.Println("請輸入聊天對象的用戶名,輸入exit退出")
fmt.Scanln(remoteUser)
forremoteUser!="exit"{
fmt.Println("請輸入聊天內(nèi)容,輸入exit退出")
fmt.Scanln(chatMsg)
forchatMsg!="exit"{
iflen(chatMsg)!=0{
msg:="to|"+remoteUser+"|"+chatMsg+"\n\n"
_,error:=c.conn.Write([]byte(msg))
iferror!=nil{
fmt.Println("conn.Writeerror....")
break
chatMsg=""
fmt.Println("請輸入聊天內(nèi)容,輸入exit退出")
fmt.Scanln(chatMsg)
c.SelectUsers()
remoteUser=""
fmt.Println("請輸入聊天對象的用戶名,輸入exit退出")
fmt.Scanln(remoteUser)
//查詢在線用戶
func(c*Client)SelectUsers(){
sendMsg:="who\n"
_,error:=c.conn.Write([]byte(sendMsg))
iferror!=nil{
fmt.Println("conn.Writeerror....")
return
//處理server返回的消息
func(c*Client)DealResponse(){
io.Copy(os.Stdout,c.conn)
func(c*Client)Run(){
forc.flag!=0{
forc.menu()!=true{
switchc.flag{
case1:
//公聊
c.PublicChat()
case2:
//私聊
c.PrivateChat()
case3:
//修改用戶名
c.UpdateName()
varserverIpstring
varserverPortint
funcinit(){
flag.StringVar(serverIp,"ip","","設(shè)置服務器IP地址(默認為)")
flag.IntVar(serverPort,"port",8888,"設(shè)置服務器端口(默認為8888)")
funcmain(){
flag.Parse()
client:=NewClient(serverIp,serverPort)
ifclient==nil{
fmt.Println("鏈接服務器失敗")
return
goclient.DealResponse()
fmt.Println("鏈接服務器成功")
client.Run()
user.go
packagemain
import(
"net"
"strings"
typeUserstruct{
Namestring
Addrstring
Cchanstring
connnet.Conn
server*Server
funcNewUser(connnet.Conn,server*Server)*User{
userAddr:=conn.RemoteAddr().String()
user:=User{
Name:userAddr,
Addr:userAddr,
C:make(chanstring),
conn:conn,
server:server,
gouser.ListenMessage()
returnuser
//用戶上線
func(u*User)Online(){
u.server.mapLock.Lock()
u.server.OnlineMap[u.Name]=u
u.server.mapLock.Unlock()
u.server.BroadCast(u,"上線")
//用戶下線
func(u*User)Offline(){
u.server.mapLock.Lock()
delete(u.server.OnlineMap,u.Name)
u.server.mapLock.Unlock()
u.server.BroadCast(u,"下線")
//給當前user的客戶端發(fā)送消息
func(u*User)SendMsg(msgstring){
u.conn.Write([]byte(msg))
//處理消息
func(u*User)DoMessage(msgstring){
ifmsg=="who"{
//查詢當前在線用戶
u.server.mapLock.Lock()
for_,user:=rangeu.server.OnlineMap{
onlineMsg:="["+user.Addr+"]"+user.Name+":在線...\n"
u.SendMsg(onlineMsg)
u.server.mapLock.Unlock()
}elseiflen(msg)7msg[:7]=="rename|"{
//修改用戶名rename|xxx
newName:=strings.Split(msg,"|")[1]
//判斷名字是否已經(jīng)存在
_,ok:=u.server.OnlineMap[newName]
ifok{
u.SendMsg("用戶名已存在\n")
}else{
u.server.mapLock.Lock()
delete(u.server.OnlineMap,u.Name)
u.server.OnlineMap[newName]=u
u.server.mapLock.Unlock()
u.Name=newName
u.SendMsg
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 中國丁腈橡膠(液體)項目投資可行性研究報告
- 自行車漲閘行業(yè)深度研究分析報告(2024-2030版)
- 中國伺服馬達用線行業(yè)市場深度分析及投資戰(zhàn)略規(guī)劃研究報告
- 中國環(huán)保型免洗助焊劑行業(yè)市場發(fā)展前景及發(fā)展趨勢與投資戰(zhàn)略研究報告(2024-2030)
- 2025年硬質(zhì)材料加工機床及其零件項目投資分析及可行性報告
- 中國電感線圈行業(yè)市場全景監(jiān)測及投資戰(zhàn)略咨詢報告
- 2025年中國反向二極管行業(yè)發(fā)展運行現(xiàn)狀及投資潛力預測報告
- 中國破碎設(shè)備行業(yè)市場評估分析及投資發(fā)展盈利預測報告
- 安全大反思大排查大整治活動總結(jié)
- 會議活動應急方案
- 2023年晉江市醫(yī)院醫(yī)護人員招聘筆試題庫及答案解析
- 水泵設(shè)備單機試運轉(zhuǎn)記錄
- 2022年鄭州市鹽業(yè)公司招聘筆試題庫及答案解析
- 景陵峪構(gòu)造報告構(gòu)造地質(zhì)學
- 小學音樂 花城版 三年級《蟲兒飛》課件
- 公共關(guān)系學-實訓項目1:公關(guān)三要素分析
- 網(wǎng)頁設(shè)計基礎(chǔ)ppt課件(完整版)
- 貴陽市建設(shè)工程消防整改驗收申請表
- GB∕T 8163-2018 輸送流體用無縫鋼管
- 機動車排放檢驗檢測方法內(nèi)部審批程序
- 吉安土地利用總體規(guī)劃
評論
0/150
提交評論