-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
service/iot: Add MQTT over websockets client #820
Comments
Hello @dhubler, thank you for reaching out to us. Those are service specific SDKs, the JS and Java SDK, and currently are only supported by those two SDKs. This would be a great feature and I will mark this as a feature request. |
As a work around, If anyone is interested, I followed instructions in
|
+1 this, we're really hurting not being able to pubsub from iot topics |
FWIW I made a library to fill the gap until the AWS SDK provides support for this: https://github.com/glassechidna/awsiot sess := session.Must(session.NewSessionWithOptions(sessOpts))
iot := awsiot.New(sess)
theUrl, _ := iot.WebsocketUrl("a1kxjqeyezkt7") // can be used with the eclipse paho mqtt library |
Just a note, as it took me a while to figure this out. It seems that @dhubler and @aidansteele solutions don't work (anymore?). IOT seems to want the X-Amz-Security-Token parameter, but it cannot be part of the canonical query parameters. It has to be added on after signing. |
@swt2c I'll check that out. I had it working a couple of weeks ago, haven't tried since. |
@swt2c @aidansteele Did you got this working? i've used @dhubler solution and appended the securityToken.. but i still get a 403 .. |
Yes, I did get it working at the time. You included the security token outside of the signature? |
@swt2c yes, did you use @dhubler example of the library by @aidansteele ? |
Yes, but unfortunately, I'm not using it anymore and don't have access to the code I was using. |
One thing to know even if you get this working, websocket connection will
reset every 24 hours. Ultimately using straight MQTT and TLS was most
reliable.
…On Mon, Jul 2, 2018, 8:36 AM Scott Talbert ***@***.***> wrote:
Yes, but unfortunately, I'm not using it anymore and don't have access to
the code I was using.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#820 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAAgfip3PIZCg3P6uWC6cA8Jl1WVDpk7ks5uCj3ugaJpZM4Jwdvx>
.
|
The solution provided by @aidansteele is still working great. |
I just had a hard time to get this working and want to share what I ended up doing.
// usage:
// addr, err := AwsIotWsUrl(sess, "xxxxx-ats.iot.eu-west-1.amazonaws.com ")
func AwsIotWsUrl(p client.ConfigProvider, endpoint string) (string, error) {
serviceName := "iotdevicegateway"
config := p.ClientConfig(serviceName)
region := *config.Config.Region
creds, err := config.Config.Credentials.Get()
if err != nil {
return "", err
}
accessKey := creds.AccessKeyID
secretKey := creds.SecretAccessKey
sessionToken := creds.SessionToken
// according to docs, time must be within 5min of actual time (or at least according to AWS servers)
now := time.Now().UTC()
dateLong := now.Format("20060102T150405Z")
dateShort := dateLong[:8]
scope := fmt.Sprintf("%s/%s/%s/aws4_request", dateShort, region, serviceName)
alg := "AWS4-HMAC-SHA256"
q := [][2]string{
{"X-Amz-Algorithm", alg},
{"X-Amz-Credential", accessKey + "/" + scope},
{"X-Amz-Date", dateLong},
{"X-Amz-SignedHeaders", "host"},
}
query := awsQueryParams(q)
signKey := awsSignKey(secretKey, dateShort, region, serviceName)
stringToSign := awsSignString(accessKey, secretKey, query, endpoint, dateLong, alg, scope)
signature := fmt.Sprintf("%x", awsHmac(signKey, []byte(stringToSign)))
return fmt.Sprintf("wss://%s/mqtt?%s&X-Amz-Signature=%s&X-Amz-Security-Token=%s", endpoint, query, signature, url.QueryEscape(sessionToken)), nil
}
func awsQueryParams(q [][2]string) string {
var buff bytes.Buffer
var i int
for _, param := range q {
if i != 0 {
buff.WriteRune('&')
}
i++
buff.WriteString(param[0])
buff.WriteRune('=')
buff.WriteString(url.QueryEscape(param[1]))
}
return buff.String()
}
func awsSignString(accessKey string, secretKey string, query string, host string, dateLongStr string, alg string, scopeStr string) string {
emptyStringHash := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
req := strings.Join([]string{
"GET",
"/mqtt",
query,
"host:" + host,
"", // separator
"host",
emptyStringHash,
}, "\n")
return strings.Join([]string{
alg,
dateLongStr,
scopeStr,
awsSha(req),
}, "\n")
}
func awsHmac(key []byte, data []byte) []byte {
h := hmac.New(sha256.New, key)
h.Write(data)
return h.Sum(nil)
}
func awsSignKey(secretKey string, dateShort string, region string, serviceName string) []byte {
h := awsHmac([]byte("AWS4"+secretKey), []byte(dateShort))
h = awsHmac(h, []byte(region))
h = awsHmac(h, []byte(serviceName))
h = awsHmac(h, []byte("aws4_request"))
return h
}
func awsSha(in string) string {
h := sha256.New()
fmt.Fprintf(h, "%s", in)
return fmt.Sprintf("%x", h.Sum(nil))
} |
this kind of subscription does not work over webscoket. using goland with paho mqtt library
I can subscribe to the jop topic but dont get any events from it. If IAM role has something like this
Then subscribed and get evens from those topics. |
Hi, our team has discussed and we decide that this feature is not implemented as this is a more cross SDK feature. |
|
Anyone got this working thought MQTT over Websockets, still struggling with it... |
With which parameters I can call the AwsIotWsUrl function? I can not call that function |
It only has Topic Publish.
This is most likely because SDK needs to use websocket protocol to get bidirectional communication.
Even if this is closed as "Will not implement", this should stand as notice API is incomplete compared with JS and Java SDKs feature set.
Also Note in source file
service/iotdataplane/service.go
We see comment:
While AWS IoT API is bi-direction capable, the AWS IoT Golang SDK is not bi-directional
The text was updated successfully, but these errors were encountered: