У меня есть сервер golang делать что-то вроде этого: пакета главногоАсинхронных сообщений golang
func main() {
for {
c := listener.Accept()
go handle(c)
}
}
...
func handle(c net.Conn) {
m := readMessage(c) // func(net.Conn)Message
r := processMessage(m) //func(Message)Result
sendResult(c, r) // func(net.Conn,Result)
}
, который считывает и записывает сообщения синхронно. Теперь мне нужно послать сообщения асинхронно через данное открытое соединение, я знаю, что канал может использоваться, я как бы потерял.
Это моя идея:
...
func someWhereElese(c chan Result) {
// generate a message and a result
r := createResultFromSomewhere()
c <- r // send the result through the channel
}
И изменить мою ручку, чтобы использовать тот же канал вместо
func handle(c net.Conn, rc chan Result) {
m := readMessage(c) // func(net.Conn)Message
r := processMessage(m) //func(Message)Result
//sendResult(c, r) // func(net.Conn,Result)
rc <- r
}
А вот где моя путаница лежит.
В результате канал должен быть создан, и он должен иметь соединение, куда послать то, что он получает
func doSend(c net.Con, rc chan Result) {
r := rc // got a result channel
sendResult(c, r) // send it through the wire
}
Но где должен быть создан этот канал? В основном цикле?
func main() {
...
for {
c := l.Accept()
rc := make(chan Result)
go doSend(c, rc)
}
}
А как насчет прочитанного? Должен ли он пойти в собственный канал/горутин? Если мне нужно транслировать до n клиентов, должен ли я хранить кусок результирующих каналов? кусок соединений?
Я здесь немного смущен, но я чувствую, что я рядом.
Начало здесь: http://talks.golang.org/2012/concurrency.slide. Ключ к вашей проблеме заключается в использовании 'select' для просмотра входящего канала соединения, канала ответа и, возможно, выхода из канала. В зависимости от вашей ожидаемой загрузки создание одного goroutine за запрос может быть прекрасным; или вам может понадобиться создать пул. Но вы поймете правильные вопросы лучше, как только пройдете Шаблоны параллелизма. См. Также http://blog.golang.org/advanced-go-concurrency-patterns и особенно «связанные статьи» в конце. Понимание 'select' является одним из великих« о, вот как работает Go! » моменты. –
@RobNapier Uhm ... Я читал слайды раньше, и я вроде как получаю их, но не совсем. Через несколько мгновений я снова пройду через них. Между тем у меня была небольшая программа, можете ли вы прокомментировать ее, если увидите что-то особенно опасное? – OscarRyz
OK; Возможно, я неправильно понял, что вы подразумеваете под «асинхронным». Я предположил, что несколько запросов и ответов будут выполняться по одному и тому же соединению (запросы чередования). Вы, похоже, имеете в виду, что хотите передавать данные, как читатель получает. Это, возможно, немного параллельнее, чем просто чтение двух байтов и запись двух байтов в одном goroutine. Вы можете посмотреть на 'golang.org/x/text/transform' для этой цели вместе с' io.Copy() '. (Извините, я не более полезен с реальным кодом здесь, это был интересный вопрос, но у меня нет времени в эту минуту, чтобы помочь экстенсивно). –