Go webrtc实现1v1聊天
offer.go
package main
import (
"bufio"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/pion/webrtc/v4"
"log"
"os"
"strconv"
"time"
)
func main() {
config := webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
}
// 1. create peer connection
peerConnection, err := webrtc.NewPeerConnection(config)
if err != nil {
return
}
defer func() {
if err := peerConnection.Close(); err != nil {
log.Println(err.Error())
}
}()
// 2. create data channel
dataChannel, err := peerConnection.CreateDataChannel("foo", nil)
dataChannel.OnOpen(func() {
log.Println("data channel has opened")
i := -1000
for range time.NewTicker(time.Second * 5).C {
if err := dataChannel.SendText("offer : hello world " + strconv.Itoa(i)); err != nil {
log.Println(err.Error())
}
}
})
dataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
fmt.Println(string(msg.Data))
})
// 3. create offer
offer, err := peerConnection.CreateOffer(nil)
if err != nil {
return
}
// 4. set local description
err = peerConnection.SetLocalDescription(offer)
if err != nil {
return
}
// 5. print offer
println("OFFER:")
println(encode(&offer))
// 6. input answer
println("请输入ANSWER:")
var answer webrtc.SessionDescription
answerStr, _ := bufio.NewReader(os.Stdin).ReadString('\n')
decode(answerStr, &answer)
// 7. set remote description
if err := peerConnection.SetRemoteDescription(answer); err != nil {
panic(err)
}
// 主循环,
select {}
}
func encode(obj *webrtc.SessionDescription) string {
b, err := json.Marshal(obj)
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString(b)
}
func decode(in string, obj *webrtc.SessionDescription) {
b, err := base64.StdEncoding.DecodeString(in)
if err != nil {
panic(err)
}
if err = json.Unmarshal(b, obj); err != nil {
panic(err)
}
}
answer.go
package main
import (
"bufio"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/pion/webrtc/v4"
"log"
"os"
"strconv"
"time"
)
func main() {
config := webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
}
// 1. create peer connection
peerConnection, err := webrtc.NewPeerConnection(config)
if err != nil {
return
}
defer func() {
if err := peerConnection.Close(); err != nil {
log.Println(err.Error())
}
}()
// 2. on data channel
peerConnection.OnDataChannel(func(dataChannel *webrtc.DataChannel) {
dataChannel.OnOpen(func() {
log.Println("data channel has opened")
i := -1000
for range time.NewTicker(time.Second * 5).C {
if err := dataChannel.SendText("answer : hello world " + strconv.Itoa(i)); err != nil {
log.Println(err.Error())
}
}
})
dataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
fmt.Println(string(msg.Data))
})
})
// 3. input offer
println("请输入OFFER:")
offerStr, _ := bufio.NewReader(os.Stdin).ReadString('\n')
var offer webrtc.SessionDescription
decode1(offerStr, &offer)
// 4. set remote description
if err := peerConnection.SetRemoteDescription(offer); err != nil {
panic(err)
}
// 5. create answer
answer, err := peerConnection.CreateAnswer(nil)
if err != nil {
panic(err)
}
// 6. set local description
if err := peerConnection.SetLocalDescription(answer); err != nil {
panic(err)
}
// 7. gather complete
gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
<-gatherComplete
// 8. print answer
fmt.Println("ANSWER:")
fmt.Println(encode1(peerConnection.LocalDescription()))
// 主循环
select {}
}
func encode1(obj *webrtc.SessionDescription) string {
b, err := json.Marshal(obj)
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString(b)
}
func decode1(in string, obj *webrtc.SessionDescription) {
b, err := base64.StdEncoding.DecodeString(in)
if err != nil {
panic(err)
}
if err = json.Unmarshal(b, obj); err != nil {
panic(err)
}
}
使用方式
go run client.go 会打印出OFFER的字符串,复制OFFER字符串到answer的OFFER输入框内,然后复制answer的ANSWER到offer的ANSWER输入框,也就是说offer与answer需要交换
go run answer.go 复制OFFER字符串到answer的OFFER输入框内,然后复制answer的ANSWER到offer的ANSWER输入框,也就是说offer与answer需要交换
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!