从单独的一直运行的go routine运行进程中抓取数据,然后将数据发送到html模板

问题描述 投票:0回答:0

我正在尝试创建一个 golang 网络应用程序,它正在侦听在我的网络上广播的数据包,然后将广播的数据包整齐地放在前端的 HTML 表中(连续)。这是我到目前为止的代码。我花了几个小时,但无法弄清楚其余的:

下面是我获取数据包的代码,然后将有关数据包的信息放入结构中。

func PacketListener(ch chan PacketStructureslice) {
    var (
        iface       = "en0"
        snaplen     = int32(1600)
        promisc     = false
        timeout     = pcap.BlockForever
        filter      = "arp" //capture packets only from that protocol
        devFound    = false
        // packetSlice = []gopacket.Packet{}
    )

    devices, err := pcap.FindAllDevs()
    if err != nil {
        log.Panicln(err)
    }
    for _, device := range devices {
        if device.Name == iface {
            devFound = true
        }
    }
    if !devFound {
        log.Panicf("Device named '%s' does not exist\n", iface)
    }
    handle, err := pcap.OpenLive(iface, snaplen, promisc, timeout)
    if err != nil {
        log.Panicln(err)
    }
    defer handle.Close()
    if err := handle.SetBPFFilter(filter); err != nil {
        log.Panicln(err)
    }

    source := gopacket.NewPacketSource(handle, handle.LinkType()) //LinkType() is the decoder to use

    for packet := range source.Packets() {
        
            view := PacketStructure{
                PacketProtocol: "ARP",
                Something: time.Now().String(),
                Number: y,
            }
            realdata.Items = append(realdata.Items, view)
            ch <- realdata
            y++
        
    }
}

此子结构稍后将参与附加到包含此子结构的一部分的另一个父结构。这将产生一片结构,每个结构都包含有关数据包的信息,然后在前端,我将遍历这片结构以创建 HTML 表。你会明白我的意思。

现在这里是前面提到的两个结构。 PacketStructSlice 是 Packetstructs 的一部分,在上面的代码中,我一直将 PacketStructure 结构附加到其中。我也在创建通道,让运行 Packetlistener 函数的 goroutine 发送数据

type PacketStructureslice struct {
    Items []PacketStructure
}

type PacketStructure struct {
    PacketProtocol string
    Something      string
    Number int
}

var Channels chan PacketStructureslice

下面是在 API 调用上执行的函数。不要担心它是如何调用的,我有一个自定义模板缓存和模板模型来将所有内容发送到前端。我只想关注如何获取信息

func (m *Repository) APIcallForGettingPackets(w http.ResponseWriter, r *http.Request) {
    go PacketListener(Channels)
    fmt.Println("Got the request")
    receiver := <-Channels
    fmt.Println(receiver) //just doing this to test

    render.RenderTemplate(w, "packets.html", &models.TemplateData{
        DataSlice: reciever.Items,
    })
}

render.RenderTemplate 只是将 reciever.Items 发送到前端。 reciever.Items 应该包含 PacketStructure 结构的切片。

现在问题来了。由于我的 PacketListener 函数永远运行,我的代码被通道请求阻塞,一切都被阻塞。我将如何创建此代码,以便我的代码获取数据包数据片段,并将其发送到前端。现在,由于我的函数在 goroutine 中永远运行,出于某种原因,当我调用通道时,我的代码也会永远运行。我需要一些方法让 goroutine 侦听数据包以继续将数据包数据附加到数据包数据片段中,并在这样做时将其显示在前端。前端是无关紧要的,但是你去吧:

<table>
  <tr>
    <th>Type</th>
    <th>Something</th>
    <th>Packet number</th>

  </tr>
  {{ range .DataSlice}}
  <tr>
    <td>{{ .PacketProtocol }}</td>
    <td>{{ .Something }}</td>
    <td>{{ .Number }}</td>
  </tr>
  {{ end}}
</table>

我是 go-routines 的新手,你可能会说,但我就是想不通。

谢谢:)

================================================= ====================

我已经尝试在API调用函数中进行通道声明,但仍然没有得到我想要的结果。但是,它确实使我的程序运行,因为它不会阻止 API 调用功能。在函数外声明通道会阻塞一切

go goroutine gorouter
© www.soinside.com 2019 - 2024. All rights reserved.