İçindekiler
- Giriş
- MOS Protokolü Temel Yapısı
- Go ile MOS Protokolü Implementasyonu
- Kod Analizi ve Örnekler
- Best Practices ve Öneriler
1. Giriş
MOS (Media Object Server) Protokolü, haber yayıncılığında kullanılan sistemler arası iletişimi standardize eden bir protokoldür. Bu makale, protokolün teknik detaylarını ve Go programlama dili ile gerçekleştirilmiş bir implementasyonunu incelemektedir.
2. MOS Protokolü Temel Yapısı
MOS protokolü, TCP/IP üzerinde çalışan, XML tabanlı bir mesajlaşma sistemi kullanır. Protokolün temel özellikleri:
- Çift port yapısı (10540 ve 10541)
- XML formatında mesajlaşma
- UCS-2 karakter kodlaması
- Heartbeat mekanizması
- Acknowledgment (ACK) sistemi
3. Go ile MOS Protokolü Implementasyonu
3.1. Temel Yapılandırma
Protokol implementasyonunun temel yapılandırması için kullanılan konfigürasyon yapısı:
1
2
3
4
5
6
7
|
type Config struct {
MsgID int `json:"msgID"`
MosID string `json:"MosID"`
NcsID string `json:"NcsID"`
MosServerIP string `json:"MosServerIP"`
RundownExportPath string `json:"RundownExportPath"`
}
|
3.2. Heartbeat Mekanizması
Sistemler arası bağlantının sürekliliğini kontrol eden heartbeat fonksiyonu:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
func HeartBeatEvent() {
logFile := &lumberjack.Logger{
Filename: "Logs/HeratBeatEvent.log",
MaxSize: 1, // 1MB rotate limiti
MaxBackups: 250, // Maksimum log dosyası sayısı
MaxAge: 28, // Log saklama süresi (gün)
Compress: true, // Gzip sıkıştırma
}
defer logFile.Close()
logger := log.New(logFile, "", log.LstdFlags)
// Üst port bağlantısı
conn, err := net.Dial("tcp", MosServerIP+":10541")
if err != nil {
fmt.Printf("Error connecting to Upperport %d: %v\n", Upperport, err)
logger.Printf("Error connecting to Upperport %d: %v\n", Upperport, err)
return
}
defer conn.Close()
// Alt port bağlantısı ve heartbeat döngüsü implementasyonu...
}
|
3.3. Rundown (Akış) İşlemleri
MOS protokolünde akış yönetimi için kullanılan temel yapılar:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
type Story struct {
XMLName xml.Name `xml:"story"`
StoryID string `xml:"storyID"`
StorySlug string `xml:"storySlug"`
StoryNum string `xml:"storyNum"`
MosExternalMetadata []*MosExternalMetadata `xml:"mosExternalMetadata"`
Item []*Item `xml:"item"`
}
type RoCreate struct {
XMLName xml.Name `xml:"roCreate"`
RoID string `xml:"roID"`
RoSlug string `xml:"roSlug"`
RoChannel string `xml:"roChannel"`
RoEdStart string `xml:"roEdStart"`
RoEdDur string `xml:"roEdDur"`
RoTrigger string `xml:"roTrigger"`
MacroIn string `xml:"macroIn"`
MacroOut string `xml:"macroOut"`
MosExternalMetadata []*MosExternalMetadata `xml:"mosExternalMetadata"`
Story []*Story `xml:"story"`
}
|
3.4. Mesaj İşleme Mekanizması
Gelen mesajların işlenmesi için kullanılan ana fonksiyon:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
func checkData(data []byte) {
var mos Structs.Mos
err := xml.Unmarshal(data, &mos)
if err != nil {
fmt.Println("Error unmarshalling XML:", err.Error())
logx("Error unmarshalling XML:" + err.Error())
return
}
switch true {
case mos.RoCreate != nil:
RunID = mos.RoCreate.RoID
RecordRundown(RunID, data, err)
sendAck(RunID)
break
case mos.RoList != nil:
RunID = mos.RoList.RoID
RecordRundown(RunID, data, err)
sendAck(RunID)
break
// Diğer mesaj tipleri için işlemler...
}
}
|
4. Önemli Implementasyon Detayları
4.1. XML İşleme
MOS protokolünde XML işleme kritik öneme sahiptir. Yapılar Go’nun xml paketini kullanarak tanımlanır:
1
2
3
4
5
6
7
8
9
|
type Mos struct {
XMLName xml.Name `xml:"mos"`
VersionAttr string `xml:"version,attr,omitempty"`
ChangeDateAttr string `xml:"changeDate,attr,omitempty"`
MosID string `xml:"mosID"`
NcsID string `xml:"ncsID"`
MessageID int `xml:"messageID"`
// Diğer alanlar...
}
|
4.2. Loglama Sistemi
Sistem olaylarının takibi için kullanılan loglama mekanizması:
1
2
3
4
5
6
7
8
9
10
11
12
|
func logx(string string) {
logFile := &lumberjack.Logger{
Filename: "Logs/MosEvent.log",
MaxSize: 1,
MaxBackups: 250,
MaxAge: 28,
Compress: true,
}
defer logFile.Close()
logger := log.New(logFile, "", log.LstdFlags)
logger.Println(string)
}
|
4.3. ACK (Onay) Mekanizması
İşlemlerin başarılı olduğunu bildiren ACK mesajları:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
func sendAck(RunID string) {
conn, err := net.Dial("tcp", MosServerIP+":10541")
if err != nil {
logx("Error connecting to Upperport: " + err.Error())
return
}
defer conn.Close()
var mos = &Structs.Mos{
MosID: MosID,
NcsID: NcsID,
MessageID: msgID,
RoAck: &Structs.RoAck{
RoID: RunID,
RoStatus: "OK",
},
}
// ACK mesajının oluşturulması ve gönderimi...
}
|
5. Best Practices ve Öneriler
5.1. Hata Yönetimi
- Her network operasyonu için timeout mekanizması kullanın
- Bağlantı kopukluklarını ele alın
- Detaylı loglama yapın
- Buffer boyutlarını optimize edin
- Gereksiz XML parse işlemlerinden kaçının
- Connection pooling kullanın
5.3. Güvenlik Önlemleri
- Tüm gelen verileri validate edin
- SSL/TLS kullanımını değerlendirin
- Access kontrolü implementasyonu yapın
6. Sonuç
MOS protokolü implementasyonu, karmaşık ancak iyi organize edilmiş bir yapıya sahiptir. Go dilinin güçlü concurrency özellikleri ve XML işleme yetenekleri, protokolün etkin bir şekilde implementasyonunu mümkün kılar. Yukarıdaki kod örnekleri ve açıklamalar, protokolün temel yapı taşlarını ve implementasyon detaylarını göstermektedir.
Başarılı bir MOS implementasyonu için:
- Protokol spesifikasyonunu detaylı anlayın
- Sağlam bir hata yönetimi mekanizması kurun
- Detaylı loglama yapın
- Performans optimizasyonlarını göz ardı etmeyin
- Güvenlik önlemlerini baştan planlayın
Bu yaklaşımla, güvenilir ve performanslı bir MOS protokolü implementasyonu gerçekleştirilebilir.