GoLang Socket 聊天實例

 收發消息實體

package model

// 發送或者接收的消息信息
type SmsMessage struct {
    // 消息 類型  1 註冊   2登陸  3在線狀態  4私聊信息   5羣發信息 6下線線狀態   7 服務端返回信息  8 服務端返回客戶端發送失敗或錯誤信息
    Type int32 `json:"type"`
    // 消息體
    Data string `json:"data"`
}

// 登陸請求信息
type SmsLogin struct {
    UserId int32 `json:"userid"`
    Pwd string   `json:"pwd"`
    UserName string `json:username`
}

// 發送註冊信息
type SmsRegister struct {
    UserInfo
}

// 發送在線狀態信息
type SmsLineStatus struct {
    // 當前用戶Id
    UserId int32 `json:"userid"`
    // 在線狀態   1, 在線,2爲 離線
    Status int32 `json:"status"`
}

// 私聊信息
type SmsToOne struct {
    // 信息發送者Id
    SendUserId int32 `json:"senduserid"`
    // 接收者Id
    ToUserId int32 `json:"touserid"`
    // 發送內容
    Context string `json:"context"`
}

// 羣發信息
type SmsToAll struct {
    // 消息發送者Id
    SendUserId int32 `json:"senduserid"`
    Context string `json:"context"`
}

// 服務端返回客戶端信息
type SmsResponse struct {
    Code int32 `json:"code"`
    OnLineUser []int32  `json:"onlineuser"`
    Error string `json:"error"`
}

// 服務端返回客戶端發送失敗或錯誤信息
type SmsErrorResponse struct {
    Code int32 `json:"code"`
    Error string `json:"error"`
}

用戶信息實體

package model

import "net"

// 用戶信息
type UserInfo struct {
    UserId int32 `json:"userid"`
    UserName string `json:"username"`
    Pwd string `json:"pwd"`
}

type UserLineMsg struct {
    UserId int32 `json:"userid"`
    Conn net.Conn `json:"conn"`
}

客戶端收發消息 服務Struct

package services

import (
    "MySocket/Commit/model"
    "encoding/binary"
    "encoding/json"
    "fmt"
    "net"
)
// 客戶端讀寫實體
type SmsReadWriteClientService struct{
    Conn net.Conn
}

// 客戶端讀取服務端發來的數據
func (this *SmsReadWriteClientService) ReadPkg() (sms model.SmsMessage,err error){
    fmt.Println("客戶端讀取服務器端發來的數據……")
    var Buf [8096]byte
    _,err =this.Conn.Read(Buf[:4])
    if err!=nil{
         fmt.Println("客戶端讀取服務器端發來的數據長度出錯:",err)
         return
    }
    var pkgLen uint32
    pkgLen=binary.BigEndian.Uint32(Buf[0:4])
    n,err:=this.Conn.Read(Buf[:pkgLen])
    if n!=int(pkgLen){
        fmt.Println("客戶端讀取服務器端發來的數據長度與接收的長度不致!")
        return
    }
    if err!=nil{
        fmt.Println("客戶端讀取服務器端發來的數據出錯:",err)
        return
    }
    err =json.Unmarshal(Buf[:pkgLen],&sms)
    if err!=nil{
        fmt.Println("客戶端讀取服務器端發來的數據返序列化出錯:",err)
        return
    }
    return
}

// 客戶端發關消息到服務器
func (this *SmsReadWriteClientService) WritePkg(data []byte) (err error){
    var Buf [8096]byte
   var pkgLen uint32
   pkgLen=uint32(len(data))
   binary.BigEndian.PutUint32(Buf[0:4],pkgLen)
   // 發送長度
   n,err :=this.Conn.Write(Buf[:4])
   if n!=4 {
       fmt.Println("客戶端發送信息長度寫實際長度不一致!")
          return
   }
   if err!=nil{
       fmt.Println("客戶端發送信息長度信息錯誤:",err)
       return
   }

   // 發送消息本身
   n,err =this.Conn.Write(data)
   if n!=int(pkgLen) {
       fmt.Println("客戶端發送消息體寫實際長度不一致!")
   }
   if err!=nil{
       fmt.Println("客戶端發送消息體寫錯誤:",err)
   }
   return
}

客戶端思路:

    定義全局變量    

package services
import (
    "MySocket/Client/model"
)
type  ConstInfo struct {

}
var (
    // 當前用戶含net.Conn的信息
    CurUer model.CurUser
)

 

// 當前用戶含net.Conn的信息
var CurUer model.CurUser

// 全局變量 在線的好友用戶Id
var oneLineUser []int32

   *用戶端連接服務器 先進行登陸,登陸成功後:

                                          1.實體化【當前用戶含net.Conn的信息】

                                           2.顯示當前所有好友 (這個信息在登陸成功時返回)

                                           3.使 用協程保持與服務器連接 去循環讀取服務端發來消息,根據不同的消息類型做不同的處理:如:好友上線,私聊、羣聊

                                           4.循環讀取前端待發的消息體,在循環體內通用Conn向服務器發送消息 

代碼如下:

   a.  客戶端Main方法 建入用戶名密碼,構建消息實體

package main

import (
    "MySocket/Client/services"
    "MySocket/Commit/model"
    "encoding/json"
    "fmt"
)


func main()  {
    for {
        var user model.UserInfo
        var UserId, UserName, Pwd = 0, "", ""
        fmt.Println("請輸入UserId……")
        fmt.Scanln(&UserId)
        user.UserId = int32(UserId)
        fmt.Println("請輸入UserName……")
        fmt.Scanln(&UserName)
        user.UserName = UserName
        fmt.Println("請輸入Pwd……")
        fmt.Scanln(&Pwd)
        user.Pwd = Pwd
        // 向服務器發送消息的結構體
        var sms model.SmsMessage
        byteUser, err := json.Marshal(user)
        if err != nil {
            fmt.Println("客戶端輸入用戶信息轉Json出錯:", err)
            return
        }
        sms.Data = string(byteUser)
        // 消息類型=2 表示登陸
        sms.Type = 2
        sendInfo := services.UserSmsProcessService{}
        // 調用這個方法進行登陸
        err = sendInfo.SendLogin(sms,user)
        if err != nil {
            fmt.Println("登陸失敗:", err)
        }
    }



}

b.      sendInfo.SendLogin(sms,user)  向服務器發送登陸信息,當登陸成功後,

                                           1.實體化【當前用戶含net.Conn的信息】

                                           2.顯示當前所有好友 (這個信息在登陸成功時返回)

                                           3.使 用協程保持與服務器連接 去循環讀取服務端發來消息,根據不同的消息類型做不同的處理:如:好友上線,私聊、羣聊

                                           4.循環讀取前端待發的消息體,在循環體內通用Conn向服務器發送消息 

 

package services

import (
    "MySocket/Commit/model"
    "encoding/json"
    "fmt"
    "io"
    "net"
    "strings"
)
var (
    // 全局變量 在線好友的用戶Id
    oneLineUser []int32
)

type UserSmsProcessService struct {
    // Conn net.Conn
}

// 用戶 登陸操作
func (this UserSmsProcessService) SendLogin(sms model.SmsMessage,user model.UserInfo) (err error){
    // 建立連接
    Conn,err :=net.Dial("tcp","127.0.0.1:8090")
    if err!=nil{
        fmt.Println("客戶端連接服務器出錯……")
        return
    }
    defer Conn.Close()
    byteSms,err :=json.Marshal(sms)
    if err!=nil{
        fmt.Println("客戶端登陸數據序列化出錯:",err)
        return
    }
    sendInfo := &SmsReadWriteClientService{Conn: Conn}
    err= sendInfo.WritePkg(byteSms)
    if err!=nil{
        fmt.Println("客戶端登陸發送到服務器出錯:",err)
        return
    }
    // 獲取登陸返回信息
    ReadInfo := &SmsReadWriteClientService{Conn: Conn}
    loginResultMsg,err := ReadInfo.ReadPkg()
    if err!=nil{
        fmt.Println("客戶端送接收登陸返回結果錯誤:",err)
        return
    }
     var response model.SmsResponse
    err = json.Unmarshal([]byte(loginResultMsg.Data),&response)
    if err!=nil{
        fmt.Println("客戶端送接收登陸返回結果返序列化錯誤:",err)
        return
    }
    if response.Code==200{
        fmt.Println("登陸200……")
        //  1.實體化【當前用戶含net.Conn的信息】
        CurUer.UserId=user.UserId
        CurUer.UserName=user.UserName
        CurUer.Conn=Conn
        oneLineUser= make([]int32,0)
        // 將當前在線的用戶添加到客戶端 全局 在線用戶上去
        oneLineUser = append(oneLineUser, response.OnLineUser...)
        // 2.顯示當前在線信息
        showinfo :=&ShowInfo{}
        showinfo.ShowOnLineUer(oneLineUser)
        /// *************** 3.保留該方法與服務端保持連接 *******************
        // 3.根據客戶端接收到不同的消息做相應的處理    這裏特別重要 *******************************
        go this.ServiceAndClientLine(Conn)
        for{    // 4.然後根據需要 隨時向服務器發送想發的消息  注意:這裏特別重要……**************************
            // 構造待發的消息體  通過輸入的方式
            smsWaitSend,err:= showinfo.ShowMenuAndEnterSendContext()
            if err!=nil{
                fmt.Println("構建羣聊或私聊包時出錯:",err)
                continue
            }
            // 發送想要發的消息
            err= sendInfo.WritePkg(smsWaitSend)
            if err!=nil{
                fmt.Println("發送羣聊或私聊出錯:",err)
            }
        }
    }else {
        fmt.Println("登陸500……")
        fmt.Println("登陸失敗")
        return
    }
    return
}



/// *************** 保留該方法與服務端保持連接 *******************
func (this *UserSmsProcessService) ServiceAndClientLine(Conn net.Conn){
    readOrWrite :=&SmsReadWriteClientService{Conn: Conn}
    for {
        fmt.Println("客戶端正在等待服務端發送消息")
        sms,err := readOrWrite.ReadPkg()
        if err!=nil{
            if strings.Contains(err.Error(),"wsarecv: An existing connection was forcibly closed by the remote host."){
                Conn.Close()
                fmt.Println("與服務器斷開了鏈接……")
                return
            }
            if err==io.EOF{
                fmt.Println("與服務器斷開了鏈接……")
                return
            }
            fmt.Println("客戶端正在等待服務端發送消息")
            continue
        }
        switch sms.Type {
            case 3:  // 有新用戶上線
                var modelStatus model.SmsLineStatus
                err:= json.Unmarshal([]byte(sms.Data),&modelStatus)
                if err!=nil{
                    fmt.Println("接收服務器用戶上線狀態反序列化失敗:",err)
                    continue
                }
                // 將新上線的用戶添加到  在線用戶列表中
                oneLineUser = append(oneLineUser, modelStatus.UserId)
                // 重新顯示在線用戶列表
                showinfo :=&ShowInfo{}
                showinfo.ShowOnLineUer(oneLineUser)
            case 4:     // 接到到的是私聊信息
                var toOne model.SmsToOne
                err:= json.Unmarshal([]byte(sms.Data),&toOne)
                if err!=nil{
                    fmt.Println("接收服務器用戶私聊信息反序列化失敗:",err)
                    continue
                }
                fmt.Println("用戶:",toOne.SendUserId,"對你發來私信:",toOne.Context)
            case 8:
                fmt.Println(sms.Data)
            default:
        }
        // 用戶自己也可以進行發送信息操作
        //showInfo :=&ShowInfo{}
        //showInfo.ShowMenuAndEnterSendContext()

    }
}

 

            上面的客戶終端輸入構建消息實體的方法及顯示在線用戶 見下:

package services

import (
    "MySocket/Commit/model"
    "encoding/json"
    "fmt"
)


type ShowInfo struct {

}

// 顯示當前在線的用戶
func (this *ShowInfo) ShowOnLineUer(users []int32){
    fmt.Println("當前在線用戶Start:")
    for _,v :=range users{
        fmt.Println(v)
    }
    fmt.Println("當前在線用戶End!")
}

/// 顯示聊天菜單,根據自身需要建立發送聊天消息,準備發送
func (this *ShowInfo) ShowMenuAndEnterSendContext() (byteSms []byte,err error){
    var codeEnter int32
    var userId int32
    var Context string
    var sms model.SmsMessage
    fmt.Println("-------4. 私聊消息---------")
    fmt.Println("-------5. 羣聊消息---------")
    fmt.Scanln(&codeEnter)
    sms.Type=codeEnter
    if codeEnter==4{
         var toone model.SmsToOne
         toone.SendUserId=CurUer.UserId
        fmt.Println("-------輸入私聊人的UserId---------")
        fmt.Scanln(&userId)
         toone.ToUserId=userId
        fmt.Println("-------輸入私聊人內容---------")
        fmt.Scanln(&Context)
         toone.Context=Context
         byteToone,err:=json.Marshal(toone)
         if err!=nil{
             fmt.Println("私聊內容序列化出錯!",err)
             return this.ShowMenuAndEnterSendContext()
         }
         sms.Data=string(byteToone)

    }else  if codeEnter==5{
         var toall model.SmsToAll
         toall.SendUserId=CurUer.UserId
         fmt.Println("-------輸入羣聊內容---------")
         fmt.Scanln(&Context)
         byteToall,err :=json.Marshal(toall)
        if err!=nil{
            fmt.Println("私聊內容序列化出錯!",err)
            return this.ShowMenuAndEnterSendContext()
        }
        sms.Data=string(byteToall)

    }else {
        fmt.Println("-------4. 私聊消息或5. 羣聊消息---------")
        return this.ShowMenuAndEnterSendContext()
    }
    byteSms,err= json.Marshal(sms)
    if err!=nil{
        fmt.Println("構建聊天消息體序列化時出錯:",err)
        return this.ShowMenuAndEnterSendContext()
    }
    return

}

 

服務端思路:

                      1.先監聽端口,循環接收客戶端連接,每個連接用一個協程來進行處理,

                      2.循環讀取各連接發來的信息

                      3.根據發來不同類型的數據進行不同處理 ,如 登陸 -- 不管成功與否---返回客戶端信息(成功還要返回在線的好友信息)

                                                                                                私聊信息-----定位私聊用戶-------向其發送私聊信息

                                                                                                 羣聊信息-----遍歷當前所有在線用戶-------分別發送羣聊信息(注意發送給各用戶的net.Conn使用*********特別注意)

服務器收發信息方法代碼

package services

import (
    "MySocket/Commit/model"
    "encoding/binary"
    "encoding/json"
    "fmt"
    "net"
)

// 發送和讀取信息
type  SmsReadWriteService struct {
    Conn net.Conn
}

// 讀取客戶端發來的信息
func (this *SmsReadWriteService) ReadPkg() (msg model.SmsMessage,err error){
    var Buf [8096]byte //這時傳輸時,使用緩衝
    fmt.Println("讀取客戶端發送的信息……")
    _,err =this.Conn.Read(Buf[:4])
    if err!=nil{
        fmt.Println("讀取客戶端送的字節數出錯:",err,"……")
        return
    }
    var pkgLen uint32
    // 將讀取到的字節數組轉化成Uint32的數據長度
    pkgLen=binary.BigEndian.Uint32(Buf[0:4])
    // 讀取該長度的數據
    n,err :=this.Conn.Read(Buf[:pkgLen])
    if n!=int(pkgLen){
        fmt.Println("服務端讀取的字節數與接收到的字節數不一致^")
        return
    }
    if err!=nil{
        fmt.Println("服務端讀取數據錯誤 :",err,"……")
        return
    }
    err = json.Unmarshal(Buf[:pkgLen],&msg)
    if err!=nil{
        fmt.Println("服務端讀取的Buf[:pkgLen]返序列化成SmsMessage出錯:",err,"……")
    }
    return
}

func (this *SmsReadWriteService) WritePkg(data []byte) (err error){
    // 先發送一個長度給對方
    var Buf [8096]byte //這時傳輸時,使用緩衝
    var pkgLen uint32
    pkgLen =uint32(len(data))
    binary.BigEndian.PutUint32(Buf[0:4],pkgLen)
    // 發送長度
    n,err :=this.Conn.Write(Buf[:4])
    if n!=4{
        fmt.Println("服務端寫入數據與發送長度不一致^")
        return
    }
    if err!=nil{
        fmt.Println("服務端寫入的Buf[:pkgLen]出錯:",err,"……")
        return
    }
    // 發送消息本身
    n,err=this.Conn.Write(data)
    if n!=int(pkgLen) {
        fmt.Println("服務端寫入數據與發送的【消息體】長度不一致^")
        return
    }
    if err!=nil{
        fmt.Println("服務端寫入消息體出錯:",err,"……")
        return
    }
    return

}

 

 

全局變量      

// 當前在線用戶Map集合 在init()方法裏實例化
OnLineUserMap map[int32]model.UserLineMsg

Main方法入口
 1.先監聽端口,循環接收客戶端連接

package main

import (
    "MySocket/Service/services"
    "fmt"
    "net"
)

func ResponseClientRequest(conn net.Conn){
    defer conn.Close()
    processService :=&services.ProcessorService{}
    // 循環接收客戶端發來的信息,然後根據消息類型來做相應的處理
    processService.ProcessorRead(conn)
}

func main()  {
    fmt.Println("服務器開始監聽127.0.0.1:8090!")
    listen,err :=net.Listen("tcp","127.0.0.1:8090")
    if err!=nil {
        fmt.Println("服務器監聽127.0.0.1:8090失敗!")
        return
    }
    defer listen.Close()
    for{
        conn,errCon:= listen.Accept()
        if errCon!=nil{
            fmt.Println("有一個連接失敗……")
            continue
        }
        fmt.Println("客戶端連接成功……")
        go ResponseClientRequest(conn)
    }

}

每個連接用一個協程來進行處理,循環讀取各連接發來的信息

package services

import (
    "MySocket/Commit/model"
    "fmt"
    "io"
    "net"
)
var (
    // 當前在線用戶Map集合
    OnLineUserMap map[int32]model.UserLineMsg
)
func init(){
    // 初始化當前  當前在線用戶Map集合
    OnLineUserMap=make(map[int32]model.UserLineMsg)
}

type ProcessorService struct {
    // Conn net.Conn
}

// 循環讀取客戶端發送過來的信息
func (this *ProcessorService)  ProcessorRead(Conn net.Conn) (err error){
    // 循環讀取客戶端發送過來的信息
    for{
        read :=&SmsReadWriteService{
            Conn: Conn,
        }
        msg,err :=read.ReadPkg()
        if err!=nil{
            if err==io.EOF{
                fmt.Println("客戶端退出,服務器端也退出..")
                return err
            }else {
                fmt.Println("readPkg err=", err)
                return err
            }
        }
        // 根據服務端接收的消息類型來做相應處理
        err =this.ProcessorReadMsg(&msg,Conn)
        if err!=nil{
            return err
        }
    }

}

// 根據服務端接收的消息類型來做相應處理
func (this *ProcessorService) ProcessorReadMsg(msg *model.SmsMessage,Conn net.Conn) (err error){

    //看看是否能接收到客戶端發送的羣發的消息
    fmt.Println("mes=", msg)
    // 消息 類型  1 註冊   2登陸  3在線狀態  4私聊信息   5羣發信息
    switch msg.Type {
    case 1: // 處理註冊信息
    case 2:
        one := &UserMsgProcessService{ // 用戶信息處理
            Conn: Conn,
        }
        // 傳遞上線信息
        one.LoginInfo(msg)
    case 3: // 3在線狀態 息
    case 4:         //4私聊信息
        toone := &UserMsgProcessService{ // 用戶信息處理
             Conn: Conn,
        }
        toone.SendToOneMsg(msg)
    case 5: // 5羣發信息

    }


    return
}

3.根據發來不同類型的數據進行不同處理 

package services

import (
    "MySocket/Commit/model"
    "encoding/json"
    "fmt"
    "net"
)

// 用戶消息處理服務
type  UserMsgProcessService struct {
    Conn net.Conn
}


//// 處理登陸信息       Start
// 處理客戶端發送過來的登陸信息
func (this *UserMsgProcessService) LoginInfo(msg *model.SmsMessage)  (err error){
    var login model.SmsLogin
    err =json.Unmarshal([]byte(msg.Data),&login)
    if err !=nil{
        fmt.Println("服務器處理登陸時出錯:",err)
        return err
    }
    var smsResponse model.SmsResponse
    if login.Pwd=="123"{
        smsResponse.Code=200
        var model model.UserLineMsg
        model.UserId=login.UserId
        model.Conn=this.Conn
        OnLineUserMap[login.UserId]=model   // 將某人上線的信息寫入到在線Map中
        userArr :=this.SendOneOnLine(login.UserId)   // 通知相關好友 當前用戶上線了,並返回當前在線的人的IduserArr
        smsResponse.OnLineUser=userArr
    } else {
        smsResponse.Code=500
        smsResponse.Error="密碼錯誤,請重新輸入……"
    }
    byteSms,err :=json.Marshal(smsResponse)
    if err!=nil{
        fmt.Println("服務器處理返回信息時smsResponse轉JSon出錯:",err)
        return err
    }
    var response model.SmsMessage
    response.Type=7
    response.Data=string(byteSms)
    // 向客戶端發送登陸是否成功的 狀態碼和錯誤 信息
    err = this.SendLoginOverToClient(response)
    return err
}


// 服務器告知相關好友,某人上線了  並返回當前在線的人的Id集userArr
func (this *UserMsgProcessService) SendOneOnLine(UserId int32) (userArr []int32){
    userArr=make([]int32,0)
    for _,v :=range OnLineUserMap{
        userArr = append(userArr,v.UserId )
        if v.UserId==UserId{
            continue
        }
        // 發送格式下的  上下線 實體
        var lineStatus model.SmsLineStatus
        lineStatus.UserId=UserId   // 誰上線了
        lineStatus.Status=3   // 上線
        // 向v用戶發送UserId 上線狀態 *****************************
        this.SendOneOnLineMsg(v,lineStatus)
    }
    return userArr
}

// 向某單個好友 發送上線用戶的上線壯態或下線壯態  status=3 上線  status=6下線
// lineStatus model.SmsLineStatus   發送的上下線實體
// lineStatus.UserId=UserId   // 誰上線了
// lineStatus.Status=3    // 上線3 下線 6
func (this *UserMsgProcessService) SendOneOnLineMsg(u model.UserLineMsg,lineStatus model.SmsLineStatus){

    byteStatus,err :=json.Marshal(lineStatus)
    if err!=nil{
        fmt.Println("服務器處理byteStatus發送用戶上線狀態時出錯:",err)
        return
    }
    // 發送消息實體
    var model model.SmsMessage
    // 消息類型 爲上下線狀態
    model.Type=lineStatus.Status
    model.Data=string(byteStatus)
    byteData,err :=json.Marshal(model)
    if err !=nil{
        fmt.Println("服務器處理byteData發送用戶上線狀態時出錯:",err)
        return
    }
    //創建消息讀寫服務實例
    sendInfo :=&SmsReadWriteService{
        Conn: u.Conn,   // 注意  這裏的Conn 是要發給誰的Conn *****************
    }
    // 向當前u用戶發送某用戶上下線消息
    sendInfo.WritePkg(byteData)
}

// 向客戶端發送登陸是否成功的 狀態碼和錯誤 信息
func (this *UserMsgProcessService) SendLoginOverToClient(model model.SmsMessage) (err error){
    byteModel,err :=json.Marshal(model)
    if err!=nil{
        fmt.Println("服務器處理登陸結果轉Json時出錯:",err)
        return  err
    }
    sendInfo :=&SmsReadWriteService{
        Conn: this.Conn,
    }
    err= sendInfo.WritePkg(byteModel)
    return err

}

//// 處理登陸信息       End


// 有客戶端發送私聊信息  處理
func (this UserMsgProcessService) SendToOneMsg(sms *model.SmsMessage) (err error){
    byteSms,err :=json.Marshal(sms)
    if err!=nil{
        fmt.Println("服務器序列化私聊整體消息時出錯:",err)
        return
    }
    var smsToOne model.SmsToOne
    err= json.Unmarshal([]byte(sms.Data),&smsToOne)
    if err!=nil{
        fmt.Println("服務器返序列化私聊消息對像時出錯:",err)
        return
    }
// 定義接收人是否存在
var userExists bool=false for _,v :=range OnLineUserMap{ if v.UserId==smsToOne.ToUserId{ userExists=true sendInfo :=&SmsReadWriteService{ Conn: v.Conn, // 注意這裏Conn的傳遞,不要傳錯***************** }
// 向私聊人發送私聊消息 err
=sendInfo.WritePkg(byteSms) if err!=nil{ fmt.Println("服務器發送私聊消息時出錯:",err) } return } }
// 假如接收人不存在
if !userExists{ var errSms model.SmsErrorResponse errSms.Code=500 errSms.Error="找不到該用戶" sms.Type=8 byteErrContext,err:= json.Marshal(errSms) if err!=nil{ fmt.Println("服務器發找不到私聊用戶返回內部信息序列化出錯:",err) return err } sms.Data=string(byteErrContext) byteErrSms,err :=json.Marshal(sms) if err!=nil{ fmt.Println("服務器發找不到私聊用戶返回整體信息序列化出錯:",err) return err } sendInfo :=&SmsReadWriteService{ Conn: this.Conn, } err= sendInfo.WritePkg(byteErrSms) } return }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章